Comments (6)
Sorry,I thought I was wrong when I submit the issue, so I closed it,
but after debugging, I found that I was right, so I reopened it.
from plthook.
Line 279 in 85dad50
Line 305 in 85dad50
Line 369 in 85dad50
We should hold the hndl (the return value of dlopen) until pltook_close.
Can you reply me?
from plthook.
lmap
points to a node of a linked list maintained by the dynamic linker.
On the other hand, POSIX doesn't define actual type of a handle returned by dlopen
.
I think ... lmap is equal to hndl,
It is correct on Linux. However it isn't on other platforms using ELF.
Linux glibc chooses to reuse lmap
as a dlopen handle.
The following code prints same two addresses on Linux.
#include <stdio.h>
#include <string.h>
#include <link.h>
#include <dlfcn.h>
int main()
{
struct link_map *lmap = _r_debug.r_map; // See link.h
while (lmap != NULL) {
if (strstr(lmap->l_name, "libc.so.6") != NULL) {
printf("%p: link_map address of libc.so.6 searched from the global variable _r_debug\n", lmap);
}
lmap = lmap->l_next;
}
printf("%p: dlopen handle of libc.so.6\n", dlopen("libc.so.6", RTLD_LAZY));
}
so, if hndl is invalid after dlclose, lmap is invalid too.
No. lmap
is valid until the dynamic library is unloaded from the process.
from plthook.
Thanks for talking with me
test.c
#include <stdio.h>
#include <string.h>
#include <link.h>
#include <dlfcn.h>
void test() {
struct link_map *lmap = _r_debug.r_map; // See link.h
while (lmap != NULL) {
if (strstr(lmap->l_name, "libtest.so") != NULL) {
printf("%p: link_map address of libtest.so searched from the global variable _r_debug\n", lmap);
} else if (strstr(lmap->l_name, "libc.so.6") != NULL) {
printf("%p: link_map address of libc.so.6 searched from the global variable _r_debug\n", lmap);
}
lmap = lmap->l_next;
}
}
int main()
{
printf("-------------------\n");
test();
printf("-------------------\n");
void* handle = dlopen("libtest.so", RTLD_LAZY);
if (handle != NULL) {
printf("%p: dlopen handle of libtest.so\n", handle);
}
printf("-------------------\n");
test();
dlclose(handle);
printf("-------------------\n");
test();
printf("-------------------\n");
return 0;
}
gcc -o test test.c -ldl
ldd test
linux-vdso.so.1 (0x00007ffe6d3fa000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f72cc1fa000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f72cbe09000)
/lib64/ld-linux-x86-64.so.2 (0x00007f72cc600000)
./test
-------------------
0x7f18128ec4f0: link_map address of libc.so.6 searched from the global variable _r_debug
-------------------
0x55b015f49690: dlopen handle of libtest.so
-------------------
0x7f18128ec4f0: link_map address of libc.so.6 searched from the global variable _r_debug
0x55b015f49690: link_map address of libtest.so searched from the global variable _r_debug
-------------------
0x7f18128ec4f0: link_map address of libc.so.6 searched from the global variable _r_debug
-------------------
Sometimes dynamic libraries are used as plugins,
if dlopen is used without linking libtest.so (such as my test.c/test), it is not ok.
your's testprog is ok, because you have linked libtest.so.
from plthook.
In https://man7.org/linux/man-pages/man3/dlclose.3.html,
The function
dlclose()
decrements the reference count on the
dynamically loaded shared object referred to by handle.If the object's reference count drops to zero and no symbols in
this object are required by other objects, then the object is
unloaded after first calling any destructors defined for the
object.
Line 374 in 85dad50
This code doesn't unload the shared library even when it is loaded by dlopen
.
if dlopen is used without linking libtest.so (such as my test.c/test), it is not ok.
In this situation, the reference count of libtest.so
increases to two at line 353
and decreases to one at line 374. The count doesn't drop to zero.
from plthook.
Thank you,I see
#include <stdio.h>
#include <string.h>
#include <link.h>
#include <dlfcn.h>
#include <plthook.h>
static double strtod_cdecl_hook_func(const char *str, char **endptr)
{
printf("strtod_cdecl_hook_func\n");
return 0;
}
int main()
{
plthook_t* plthook = NULL;
const char* filename = "libtest.so";
plthook_open(&plthook, filename);
unsigned int pos = 0;
const char* name = NULL;
void **addr = NULL;
const char* funcname = "strtod_cdecl";
unsigned int found = 0;
while (plthook_enum(plthook, &pos, &name, &addr) == 0) {
if (strcmp(funcname, name) == 0) {
found = 1;
break;
}
}
if (0 != found)
{
plthook_replace(plthook, funcname, (void*)strtod_cdecl_hook_func, NULL);
}
plthook_close(plthook);
// strtod_cdecl("3.7", NULL);
return 0;
}
gcc -o test test.c ../plthook_elf.c -ldl
My previous idea was not to link libtest.so when compiling, such as above.
But i found i was wrong.
(1) I can not call strtod_cdecl whitout linking libtest.so, Unless I explicitly call the dlopen and dlsym.
(2) https://man7.org/linux/man-pages/man3/dlclose.3.html,
RTLD_NOLOAD (since glibc 2.2)
Don't load the shared object. This can be used to test if
the object is already resident (dlopen() returns NULL if
it is not, or the object's handle if it is resident).
This flag can also be used to promote the flags on a
shared object that is already loaded. For example, a
shared object that was previously loaded with RTLD_LOCAL
can be reopened with RTLD_NOLOAD | RTLD_GLOBAL.
Line 353 in 85dad50
If I do not link libtest.so, Line 353 hndl is NULL.
(3) if i don't link libtest.so and don't call strtod_cdecl in main, strtod_cdecl doesn't appear in Dynamic Relocation Symbol Table.
It's not PLT than delayed binding.
I see, Thank you
from plthook.
Related Issues (20)
- Possible buffer overflow HOT 1
- I try to hook "glDrawElements", but it doesn't work. HOT 2
- [Android] Hook dlopen HOT 1
- Failed to find symbol when using C# runtime. HOT 2
- plthook_elf.c: plthook_open() fails on executables with local hint symbols (__INIT_ARRAY, _end) HOT 1
- None of _start, _end and __INIT_ARRAY__ present in library HOT 6
- How to hook a member function of some class in C++ ? HOT 2
- plthook_replace error: no such function: malloc HOT 2
- A minor typo issue.
- ssize_t rv was not decleared HOT 1
- undefined reference to `plthook_open` HOT 1
- Why mprotect not needed for osx? HOT 2
- Hook function inside shared library opened via `dlopen()` with `RTLD_DEEPBIND`? HOT 2
- hook function from vtable
- Library doesn't support the new LC_DYLD_CHAINED_FIXUPS and LC_DYLD_EXPORTS_TRIE macos linker commands HOT 5
- Could not find memory region containing address HOT 1
- Can I hook the function called by a referenced library? HOT 6
- Not found function "recv" and any functions from Socket API in libc HOT 2
- plthook issues on MacOS HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from plthook.