Closed rdbo closed 10 months ago
Tests (not 100% pair to pair, but anyways):
testing map_files
[*] enumerate modules with libmem
module: /proc/20824/root/dir/Repos/map-files-test/main 5577bd250000-5577bd255000
module: /proc/20824/root/usr/lib/libstdc++.so.6.0.32 7f2aa9000000-7f2aa9295000
module: /proc/20824/root/usr/lib/liblibmem.so 7f2aa9400000-7f2aa9d1e000
module: /proc/20824/root/usr/lib/libgcc_s.so.1 7f2aa9e26000-7f2aa9e4a000
module: /proc/20824/root/lib/ld-musl-x86_64.so.1 7f2aa9e4a000-7f2aa9eea000
[*] finished - time: 0.000405
[*] enumerate modules with /proc/<pid>/map_files
module: /dir/Repos/map-files-test/main 5577bd250000-5577bd255000
module: /usr/lib/libstdc++.so.6.0.32 7f2aa9000000-7f2aa9295000
module: /usr/lib/liblibmem.so 7f2aa9400000-7f2aa9d1e000
module: /usr/lib/libgcc_s.so.1 7f2aa9e26000-7f2aa9e4a000
module: /lib/ld-musl-x86_64.so.1 7f2aa9e4a000-7f2aa9eea000
[*] finished - time: 0.000287
[*] press enter to exit...
The map_files
method takes slightly less time. This difference is way more noticeable on processes with huge /proc/<pid>/maps
(contains both allocations and modules), which would take a long time to parse. Meanwhile, the map_files
directory only contains modules, and should take a constant amount of time based on the amount of loaded modules.
Tests with a full-of-allocations /proc/<pid>/maps
:
int main()
{
clock_t start;
clock_t end;
size_t i;
printf("doing useless random allocations to fill /proc/self/maps\n");
for (i = 0; i < 10000; ++i) {
int prot = random() & (PROT_EXEC | PROT_READ | PROT_WRITE);
void *_alloc = mmap(NULL, sysconf(_SC_PAGESIZE), prot, MAP_PRIVATE | MAP_ANON, -1, 0);
}
printf("testing map_files\n");
printf("[*] enumerate modules with libmem\n");
start = clock();
LM_EnumModules(lm_callback, NULL);
end = clock();
printf("[*] finished - time: %lf\n", (double)(end - start) / CLOCKS_PER_SEC);
printf("[*] enumerate modules with /proc/<pid>/map_files\n");
start = clock();
enum_modules(callback);
end = clock();
printf("[*] finished - time: %lf\n", (double)(end - start) / CLOCKS_PER_SEC);
printf("[*] press enter to exit...\n");
scanf("%*c");
return 0;
}
Output:
doing useless random allocations to fill /proc/self/maps
testing map_files
[*] enumerate modules with libmem
module: /proc/29048/root/dir/Repos/map-files-test/main 5592f409f000-5592f40a4000
module: /proc/29048/root/usr/lib/libstdc++.so.6.0.32 7fdd23e00000-7fdd24095000
module: /proc/29048/root/usr/lib/liblibmem.so 7fdd24200000-7fdd24b1e000
module: /proc/29048/root/usr/lib/libgcc_s.so.1 7fdd24b27000-7fdd24b4b000
module: /proc/29048/root/lib/ld-musl-x86_64.so.1 7fdd24b4b000-7fdd24beb000
[*] finished - time: 0.025560
[*] enumerate modules with /proc/<pid>/map_files
module: /dir/Repos/map-files-test/main 5592f409f000-5592f40a4000
module: /usr/lib/libstdc++.so.6.0.32 7fdd23e00000-7fdd24095000
module: /usr/lib/liblibmem.so 7fdd24200000-7fdd24b1e000
module: /usr/lib/libgcc_s.so.1 7fdd24b27000-7fdd24b4b000
module: /lib/ld-musl-x86_64.so.1 7fdd24b4b000-7fdd24beb000
[*] finished - time: 0.000923
[*] press enter to exit...
In this second test, with a /proc/<pid>/maps
full of allocations, the map_files
method performed the same task as LM_EnumModules
in about 1 / 25
of the time. Which solidifies this method.
Again, the tests are not 100% equal. But the disparity between the methods is too big for it to be ignored.
After 2153ed56133c5052aead76b1605bd8a202967ca2:
doing useless random allocations to fill /proc/self/maps
testing map_files
[*] enumerate modules with libmem
module: /proc/27268/root/dir/Repos/map-files-test/main 55a8b1285000-55a8b128a000
module: /proc/27268/root/usr/lib/libstdc++.so.6.0.32 7f3b8ce00000-7f3b8d095000
module: /proc/27268/root/dir/Repos/map-files-test/liblibmem.so 7f3b8d200000-7f3b8db1e000
module: /proc/27268/root/usr/lib/libgcc_s.so.1 7f3b8db30000-7f3b8db54000
module: /proc/27268/root/lib/ld-musl-x86_64.so.1 7f3b8db54000-7f3b8dbf4000
[*] finished - time: 0.001146
[*] enumerate modules with /proc/<pid>/map_files
module: /dir/Repos/map-files-test/main 55a8b1285000-55a8b128a000
module: /usr/lib/libstdc++.so.6.0.32 7f3b8ce00000-7f3b8d095000
module: /dir/Repos/map-files-test/liblibmem.so 7f3b8d200000-7f3b8db1e000
module: /usr/lib/libgcc_s.so.1 7f3b8db30000-7f3b8db54000
module: /lib/ld-musl-x86_64.so.1 7f3b8db54000-7f3b8dbf4000
[*] finished - time: 0.000616
[*] press enter to exit...
Even with huge maps files, it no longer slows down.
This could significantly increase the speed of retrieving modules on Linux, specially for big processes that do a lot of allocations and have a lot of modules. It should also be checked whether this works on BSDs and Android as well.