hirthwork 27.12.2012 18:34 mcabber

Дано:
1. имя .so-шки
2. имя символа
Задача:
1. загрузить .so-шку
2. пространства имён у одной .so-шки загруженной дважды должны быть раздельными
3. отыскать в .so-шке символ и вызвать его
4. символы текущего бинаря должны быть видны изнутри .so-шки

Решение:
0. Не подошло: dlmopen(LM_ID_NEWLM,...) — не выполняется п.4
1. делаем int fd = mkstemp("mytemplateXXXXXX");
2. чтобы не запариваться с выставленным/пустым TMPDIR, делаем
readlink("/proc/self/fd/<fd>", name, len), получаем полное имя временного файла
3. fchmod(fd, S_IRUSR | S_IWUSR | S_IXUSR)
4. делаем void* handle = dlopen(<имя .so-шки>, RTLD_NOW | RTLD_NOLOAD)
4.1. handle == NULL: handle = dlopen(<имя .so-шки>, RTLD_NOW)
4.1.1. void* sym = dlsym(handle, <имя символа>)
4.2. handle != NULL: void* sym = dlsym(handle, <имя символа>);
4.2.1. dladdr(sym, &dlinfo);
4.2.2. копируем содержимое dlinfo.dli_fname в fd
4.2.3. fsync(fd)
4.2.4. handle = dlopen(name, RTLD_NOW)
4.2.5. sym = dlsym(handle, <имя символа>)
5. в кои-то веки вызываем символ

Linux — это просто и понятно!

1. magog 27.12.2012 18:38 Azoth

а как такое же под вендой сделать?

2. hirthworkmagog /1 27.12.2012 18:40 mcabber

под виндой, ЕМНИП, п.4 из постановки задачи реализовать невозможно

3. magoghirthwork /2 27.12.2012 18:41 Azoth

даааа, Тогда венда — это просто и понятно. Ты просто понимаешь, что это не возможно сделать и все

4. hirthwork 27.12.2012 18:44 mcabber

UPD: пп. 4.2. и 4.2.1 можно заменить одним вызовом dlinfo(handle, RTLD_DI_CONFIGADDR, &dlinfo)

5. 4da 27.12.2012 18:56 BitlBee

охуеть. а зачем нужен п.4 ? разве нельзя правильно задизайнить so-шку/написать переходник?

6. hirthwork4da /5 27.12.2012 18:58 mcabber

.so-шка задизайнена правильно

7. hirthwork 27.12.2012 19:01 mcabber

UPD2: по совокупности первых трёх тегов пп.1-3. можно заменить на name = tmpnam(NULL) && fd = open(name, O_EXCL)

8. hirthworkhirthwork /6 27.12.2012 19:03 mcabber

объясню, хочется работать со старой версией загруженной .so-шки до тех пор пока не удастся успешно вызвать функцию инициализации. т.е. сначала сделать dlclose(), а потом dlopen() нельзя

9. hirthwork 27.12.2012 19:22 mcabber

UPD3: в /4 я напиздел. папку, в которой лежит файл можно получить через RTLD_DI_ORIGIN

10. magoghirthwork /9 27.12.2012 19:25 Azoth

ПИЗДОБОЛ!!!

11. 238328 27.12.2012 19:50 24045556891356637487575343

это нужно менее 5% пользователям — всем пофиг

12. hirthwork238328 /11 27.12.2012 19:51 mcabber

почему твой ник совпадает с TMP_MAX?

13. 238328hirthwork /12 27.12.2012 19:52 24045556891356637487575343

лол?

14. 238328hirthwork /12 27.12.2012 19:52

я хакир просто

15. ulidtko 27.12.2012 20:31

ты что-то такое черезжопное делаешь, срсли

16. hirthworkulidtko /15 27.12.2012 20:32 mcabber

см. /8

17. hirthwork 27.12.2012 21:50 mcabber

реализовал. от изначального плана отличается только тем что mkstemp нужно передавать полный путь, учитывается /4 и /7, которое пришпиндоривается к basename от пути к файлу, ну и плюс имя файла берётся как есть, если оно начинается со слеша, без вызовов к dlinfo

18. hirthworkhirthwork /17 27.12.2012 21:51 mcabber

и да. я знаю, то что всё сделанное является чем-то противоестественным, но другого пути я не нашёл :(

Do you really want to delete ?