Сейчас на форуме: tyns777, zds, JustLife, 2nd, morgot (+5 невидимых)

 eXeL@B —› Программирование —› Выгрузка либы
Посл.ответ Сообщение

Ранг: 16.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 22 мая 2009 05:54
· Личное сообщение · #1

Есть лист из либы:

Code:
  1. Function MsgProc (Code, WParam, LParam : DWord) : DWord; StdCall;
  2. Begin
  3.   CallNextHookEx (SH, Code, WParam, LParam);
  4. End;
  5. Procedure DllEntryPoint (Reason : DWord);
  6. Var
  7.   CaMutex : Cardinal;
  8. Begin
  9.   Case Reason of
  10.     Dll_Process_Attach :
  11.     Begin
  12.       CaMutex := CreateMutex (Nil, False, 'MyZone');
  13.       If CaMutex = 0 Then
  14.         Exit;
  15.       SetWindowsHookEx (WH_GetMessage, @MsgProc, HInstance, 0);
  16.     End;
  17.     Dll_Process_detach :
  18.       UnHookWindowsHookEx (SH);
  19.   End;
  20. End;
  21. begin
  22.   DllProc := @DllEntryPoint;//
  23.   DllEntryPoint (Dll_Process_Attach);
  24. end.


как правильно выгрузить данную либу?

Заранее спс



Ранг: 516.1 (!), 39thx
Активность: 0.280
Статус: Участник

Создано: 22 мая 2009 06:52
· Личное сообщение · #2

FreeLibrary



Ранг: 16.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 22 мая 2009 07:00
· Личное сообщение · #3

Не катит FreeLibrary, проверил

Var
LibaHandle : Cardinal;
Begin
Libahandle := GetModuleHandle ('MyDll.Dll');
FreeLibrary (LibaHandle);
End;



Ранг: 16.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 22 мая 2009 08:11
· Личное сообщение · #4

Выгружаю либу, только непонятно вот тут:

FreeLibrary (Ca);
FreeLibrary (Ca);
FreeLibrary (Ca);



66d9_22.05.2009_CRACKLAB.rU.tgz - Dll.rar




Ранг: 127.3 (ветеран), 44thx
Активность: 0.090
Статус: Участник

Создано: 22 мая 2009 11:27 · Поправил: zeppe1in
· Личное сообщение · #5

а может
Ca := LoadLibrary('MyDll.Dll');

вот у тебя написано

Ca := GetModuleHandle ('Din.Dll');
LoadLibrary ('Din.Dll');

а GetModuleHandle возвращает хендл загруженного модуля, тоесть в твоём случае возвращаеца 0.

-----
zzz





Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 22 мая 2009 20:40
· Личное сообщение · #6

FreeLibrary прекрасно подходит, но, как говорил Рихтер, тут есть одно но - т.к. количество потоков в приложении, в которое данная либа была внедрена, не всегда (далеко не всегда) равно нулю, это приводит к тому, что для выгрузки из адресного пространства такого процесса данной библиотеки код, её выгружающий, должен выполниться столько раз, сколько потоков имеет процесс. Т.е. проверяем через GetModuleHandle, присутствует ли либа, если возвращается валидный хэндл, то выполняем FreeLibrary, и так столько раз, сколько будет нужно. Так проще, т.к. не нужно вычислять, сколько на данный момент потоков у процесса.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 23 мая 2009 00:05
· Личное сообщение · #7

ARCHANGEL
Потоки непричём. Существует счётчик загрузок(LDR_DATA_TABLE_ENTRY.LoadCount). Это значение увеличивается каждый раз при вызове функций загружающих модуль и уменьшается при попытках выгрузить соответственно. Если значение станет равным нулю модуль быдет выгружен. Тоесть туда нужно единицу запихать а потом уже выгружать(для статически прилинкованных не прокатит).



Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 23 мая 2009 00:11
· Личное сообщение · #8

плюс к выше сказанному, увеличение идёт функцией LdrAddRefDll.

-----
Shalom ebanats!




Ранг: 16.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 23 мая 2009 03:52
· Личное сообщение · #9

Как подсчитать, скока раз надо вызвать FreeLibrary?



Ранг: 516.1 (!), 39thx
Активность: 0.280
Статус: Участник

Создано: 23 мая 2009 09:03
· Личное сообщение · #10

50Hz_220B_1200W, может msdn поставишь и избавишь себя и людей от этих вопросов?



Ранг: 16.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 23 мая 2009 09:08 · Поправил: 50Hz_220B_1200W
· Личное сообщение · #11

качаю сейчас русс. MSDN, потом не буду этих задавать вопросов
______________________________________________________
Лучше плохой учитель, чем хорошая книга



Ранг: 0.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 23 мая 2009 12:04 · Поправил: only
· Личное сообщение · #12

50Hz_220B_1200W пишет:
Как подсчитать, скока раз надо вызвать FreeLibrary?

- через список структур загрузчика как выше написал клерк
Code:
  1. TEB(fs:[0x18])::PEB::PEB_LDR_DATA::LDR_DATA_TABLE_ENTRY.LoadCount





Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 26 мая 2009 12:39
· Личное сообщение · #13

Внимательно прочитав Рихтера, нашёл:


На самом деле LoadLibrary и LoadLibraryEx лишь увеличивают счетчик числа поль-
зователей указанной библиотеки, a FreeLibrary и FreeLibraryAndExitThread его умень-
шают. Так, при первом вызове LoadLibrary для загрузки DLL система проецирует об-
раз DLL-файла на адресное пространство вызывающего процесса и присваивает еди-
ницу счетчику числа пользователей этой DLL. Если поток того же процессу вызывает
LoadLibrary для той же DLL еще раз, DLL больше не проецируется; система просто
увеличивает счетчик числа ее пользователей — вот и все.
Чтобы выгрузить DLL из адресного пространства процесса, FreeLibrary придется
теперь вызывать дважды: первый вызов уменьшит счетчик до 1, второй — до О. Обна-
ружив, что счетчик числа пользователей DLL обнулен, система отключит ее. После
этого попытка вызова какой-либо функции из данной DLL приведет к нарушению
доступа, так как код по указанному адресу уже не отображается на адресное простран-
ство процесса.
Система поддерживает в каждом процессе свой счетчик DLL, т. е. если поток
процесса А вызывает приведенную ниже функцию, а затем тот же вызов делает поток
в процессе В, то MyLib.dll проецируется на адресное пространство обоих процессов,
а счетчики числа пользователей DLL в каждом из них приравниваются 1.
HINSTANCE hinstDll = LoadLibrary("MyLib.dllT1);
Если же поток процесса В вызовет далее:
FreeLibrary(hinstDll);
счетчик числа пользователей DLL в процессе В обнулится, что приведет к отключе-
нию DLL от адресного пространства процесса В. Но проекция DLL на адресное про-
странство процесса А не затрагивается, и счетчик числа пользователей DLL в нем
остается прежним.
Чтобы определить, спроецирована ли DLL на адресное пространство процесса,
поток может вызвать функцию GetModuleHandte;
HINSTANCE GetModuleHandle(PCTSTR pszModuleName); •
Например, следующий код загружает MyLib.dll, только если она еще не спроеци-
рована на адресное пространство процесса:
HINSTANCE hinstDll = Get Mod uleH arid le( "MyLib"); // подразумевается расширение .dll
if (hinstDll == NULL) {
hinstDll = LoadLibraryC'MyLib"); // подразумевается расширение .dll

Так что не стоит использовать какие-то не очень документированные структуры, когда документированные просты и понятны.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 0.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 26 мая 2009 13:34
· Личное сообщение · #14

по-моему проще анмепнуть секцию модуля (NtUnmapViewOfSection) и пофигу все эти ссылки




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 27 мая 2009 12:14
· Личное сообщение · #15

only
Если я правильно понял, то тогда не выполнится код, который должен выполняться по Dll_Process_detach. А это - не есть гуд.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 0.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 27 мая 2009 13:36
· Личное сообщение · #16

ARCHANGEL
ну да.
хуки и подобный мусор конечно снять нужно, перед анмэпом.



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 27 мая 2009 15:28 · Поправил: Clerk
· Личное сообщение · #17

> Система поддерживает в каждом процессе свой счетчик DLL, т. е. если поток
процесса А вызывает приведенную ниже функцию, а затем тот же вызов делает поток
в процессе В, то MyLib.dll проецируется на адресное пространство обоих процессов,
а счетчики числа пользователей DLL в каждом из них приравниваются 1.

Полнейший бред, написанный кемто не понимающим что есть поток и процесс. Адресное простнаство не зря называется виртуальным, изолированность это главное требование безопасности.
> NtUnmapViewOfSection
Проекция модуля перестанет существовать в памяти, ссылки на неё останутся, все будут думать что модуль есть, код не выполнит необходимые действия например при выгрузке. В конце концов приведёт к эксцепшину и краху в простейшем случае лоадера.



Ранг: 500.5 (!), 8thx
Активность: 0.230
Статус: Участник

Создано: 27 мая 2009 15:54 · Поправил: Smon
· Личное сообщение · #18

ARCHANGEL пишет:
На самом деле LoadLibrary и LoadLibraryEx лишь увеличивают счетчик числа поль-
зователей указанной библиотеки, a FreeLibrary и FreeLibraryAndExitThread его умень-
шают. Так, при первом вызове LoadLibrary для загрузки DLL система проецирует об-
раз DLL-файла на адресное пространство вызывающего процесса и присваивает еди-
ницу счетчику числа пользователей этой DLL. Если поток того же процессу вызывает
LoadLibrary для той же DLL еще раз, DLL больше не проецируется; система просто
увеличивает счетчик числа ее пользователей — вот и все.
Чтобы выгрузить DLL из адресного пространства процесса, FreeLibrary придется
теперь вызывать дважды: первый вызов уменьшит счетчик до 1, второй — до О. Обна-
ружив, что счетчик числа пользователей DLL обнулен, система отключит ее. После
этого попытка вызова какой-либо функции из данной DLL приведет к нарушению
доступа, так как код по указанному адресу уже не отображается на адресное простран-
ство процесса.

Истена, файло отдельно проецируется на адресное пространство каждого процесса, иначе завалились бы при первом же сплайсе, счётчики количества LoadLibrary/FreeLibrary реально есть - только что проверил ради интереса, для каждого процесса свой счётчик, считал ранее что для получения адреса загруженной библиотеки не обязательно юзать GetModuleHandleA, можно обойтись и LoadLibrary, а там вон какая фишка

-----
"Пусть видят, что мы не шутим. Стволы для понта, ножи для дела" Lock, Stock & Two Smoking Barrels




Ранг: 0.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 27 мая 2009 16:21
· Личное сообщение · #19

Clerk
Проекция модуля перестанет существовать в памяти, ссылки на неё останутся, все будут думать что модуль есть, код не выполнит необходимые действия например при выгрузке. В конце концов приведёт к эксцепшину и краху в простейшем случае лоадера.
скорее всего это верно только для модуля который статически прилинкован.
если иначе, то какие такие необычные ссылки могут быть на модуль(с учетом например того, что все хуки в коде и данных, возможно установленные и данным модулем, сняты, и ссылка на модуль удалена из области памяти лоадера)?
может конечно имеются ввиду потоки которые быть созданы кодом из модуля и могли исполнять код модуля в момент удаления его проекции
тогда можно ловить все без разбора исключения для данного процесса и удалять потоки в контексте которых eip указывает на область памяти модуля
хотя и свои потоки могли оказаться в таком же положении (тоже ведь можно придумать что-то - они все-таки "свои")




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 27 мая 2009 17:26
· Личное сообщение · #20

Этот текст написан для винды 9х, где либы были 1 на все процессы. Изменение либы в 1 месте, меняло её везде. Поэтому текст не совсем бред, просто старый и уже неактуален.



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 27 мая 2009 19:49 · Поправил: Clerk
· Личное сообщение · #21

only
> какие такие необычные ссылки могут быть на модуль
Запись в лдр. Любая функция из Ldr* юзает проверку валидности хидера к примеру, RtlImageNtHeader(), хотя и заключена в сех чтоб не упала, но это общее состояние загрузчика нарушит. Как же импорт/экспорт - другие модуля будут обращаться в никуда, а внутренние хэши, нотификаторы и пр.


 eXeL@B —› Программирование —› Выгрузка либы
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати