Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];

Вниз

Dll injection   Найти похожие ветки 

 
nomshar   (2004-09-26 17:46) [0]

Внедрил свою dll в SysListView32 (для тех, кто не знает, иерархия такая: Progman -> SHELLDLL_DefView -> SysListView32). Все нормально, хук установился, оконная процедура заменилась. В общем, работает. Одна только проблема. Как выгрузить эту dll-ку, не перезагружая explorer.exe.
Бился я довольно-таки долго. Даже предка менял (SetParent), но ничего не помогло, хотя и не могло помочь. У каждого процесса хендл одной и той же библиотеки разный.
Есть вариант внедрения в код explorer.exe и выгрузка уже из него этой самой библиотеки. Но как это сделать? А может есть и другие варианты. Обратился к Рихтеру. У него по этому поводу ничего не сказано.
Может кто-нибудь уже сталкивался с этой проблемой и решил ее или есть какие-нибудь идеи. Подскажите, буду благодарен. Тема очень интересная и веселая, особенно, когда пользователь видит, что знакомая ему с "ранних лет" программа чудит что-то невообразимое. :)


 
Cobalt ©   (2004-09-26 20:35) [1]

Клин клином вышибают.
Хуком внедрил - хуком и выгружай.
Точно также меняй процедуру окна и делай FreeLibrary.
После снятия хука твоя длл-ка выгрузится.


 
nomshar   (2004-09-27 13:49) [2]

> Cobalt. То есть ты хочешь сказать, что мне необходимо внедрить ее одну dll-ку?!
Плюс, dll-ка сама себя выгрузить не может.


 
Digitman ©   (2004-09-27 13:59) [3]


> nomshar


чего ты мудришь ?
снимай свой глоб.хук вызовом UnhookWindowsHookEx - и всех делов-то ! ... при снятии хука образы хук-ДЛЛ будут выгружены из АП всех процессов, куда они были загруженгы при соотв.установке хука


 
Cobalt ©   (2004-09-27 14:41) [4]

2 nomshar   (27.09.04 13:49) [2]
Тут получается - не совсем  сама себя - её система выгрузит.
А про FreeLibrary - ты ведь, после того, как хук поставил и сменил оконную процедуру - сделал LoadLibrary для длл (чтобы после снятия хука функция из длл-ки осталась в АП процесса) и снял хук?


 
kaZaNoVa ©   (2004-09-27 22:14) [5]

это похоже на то, что я раньше делал - внедрял длл и стартовал поток ...
- в потоке loadlibrary, после снятия хука dll НЕ выгружалась .. :)


 
nomshar   (2004-09-29 18:28) [6]

> Digiman. Извини, но ты несколько не прав. Что такое хук?! Это всего лишь способ перехвата событий. Да его надо обязательно ставить из dll. Это правильно. Но я же свою библиотеку внедряю в другой процесс. И, скажем так, вынедрить ее может только он сам. В данном случаей explorer.exe.

> Cobalt. Я так понял, ты имеешь в виду способ внедрения с двуями dll. Я же использую всего лишь одну: в ней и ставиться хук, и подменяется оконная процедура.
Про твой вопрос.
Привожу код dll.


library injectdll;

{ Important note about DLL memory management: ShareMem must be the
 first unit in your library"s USES clause AND your project"s (select
 Project-View Source) USES clause if your DLL exports any procedures or
 functions that pass strings as parameters or function results. This
 applies to all strings passed to and from your DLL--even those that
 are nested in records and classes. ShareMem is the interface unit to
 the BORLNDMM.DLL shared memory manager, which must be deployed along
 with your DLL. To avoid using BORLNDMM.DLL, pass string information
 using PChar or ShortString parameters. }

uses
 SysUtils,
 Classes,
 messages,
 windows,
 ShellAPI;

const
 SUCCESS = 10100;
 FAILED =  10101;
 UNNABLE_TO_LOAD_DLL = 10110;
 PAINTED = 10111;

{$R *.res}

var
 Injected: boolean = false;
 myHook: HHOOK;
 SavedProc: pointer;
 ButtonCreated: boolean = false;

function GethWnd: HWND;
begin
result:= FindWindowEx(0, 0, "Progman", nil);
result:= FindWindowEx(result, 0, "SHELLDLL_DefView", nil);
result:= FindWindowEx(result, 0, "SysListView32", nil);
end;

// Взято из Delphi World!
function GetOSInfo: string;
var
 Platform: string;
 BuildNumber: Integer;
begin
 case Win32Platform of
   VER_PLATFORM_WIN32_WINDOWS:
   begin
     Platform := "Windows 95";
     BuildNumber := Win32BuildNumber and $0000FFFF;
   end;
   VER_PLATFORM_WIN32_NT:
   begin
     Platform := "Windows NT";
     BuildNumber := Win32BuildNumber;
   end;
   else
   begin
     Platform := "Windows";
     BuildNumber := 0;
   end;
 end;
 if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) or (Win32Platform = VER_PLATFORM_WIN32_NT) then
 begin
   if Win32CSDVersion = "" then
     result := Format("%s %d.%d (Build %d)", [Platform, Win32MajorVersion, Win32MinorVersion, BuildNumber])
   else
     result := Format("%s %d.%d (Build %d: %s)", [Platform, Win32MajorVersion, Win32MinorVersion, BuildNumber, Win32CSDVersion]);
 end
 else
   result := Format("%s %d.%d", [Platform, Win32MajorVersion, Win32MinorVersion])
end;

procedure DoSomething(myWnd: HWND);
var r: TRect;
   dc: HDC;
   str: string;
   BtnWnd: HWND;
begin
 r:= Rect(0, 0, 0, 0);
 dc:= GetDC(myWnd);
 SetTextColor(dc, rgb(255, 255, 255));
 SetBkMode(dc, TRANSPARENT);
 GetWindowRect(myWnd, r);
 m.dwLength:= sizeOf(m);
 str:= "Your system is: " + GetOSInfo;
 DrawText(dc, PChar(str), Length(str), r, DT_TOP or DT_RIGHT);
 ReleaseDC(myWnd, dc);
end;

procedure CreateButton;
var h: HWND;
   r: TRect;
begin
if not ButtonCreated then
 begin
  r:= Rect(0, 0, 0, 0);
  GetWindowRect(GethWnd, r);
  h:= CreateWindow("BUTTON", "ClickMe", WS_CHILD or BS_PUSHBUTTON,
                        r.Right - 85, r.Top + 50, 75, 25, GethWnd, hMenu(123), 0, 0);
  ShowWindow(h, SW_SHOW);
  ButtonCreated:= true;
 end;
end;

function MyWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
DoSomething(hWnd);
CreateButton;
case Msg of
  WM_PAINT: PostMessage(FindWindow(0, "Form1"), WM_USER + 100, 0, PAINTED);

 end;
if ButtonCreated then
 begin
  case Msg of
   WM_COMMAND: begin
                case HiByte(wParam) of
                  BN_CLICKED:
                    PostMessage(FindWindow(0, "Form1"), WM_USER + 100, 0, 123);
                end;
               end;
  end;
 end;
result:= CallWindowProc(SavedProc, hWnd, Msg, wParam, lParam);
end;

procedure SetWndProc(hWnd: HWND);
begin
if pointer(GetWindowLong(hWnd, GWL_WNDPROC)) <> @myWndProc then
 begin
  SavedProc:= pointer(SetWindowLong(hWnd, GWL_WNDPROC, cardinal(@myWndProc)));
 end;
end;

function myHookProc(nCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
if not Injected then
 begin
  if loadLibrary("injectdll.dll") <> 0 then
   SetWndProc(GethWnd)
  else
   PostMessage(FindWindow(0, "Form1"), WM_USER + 100, 0, UNNABLE_TO_LOAD_DLL);

  Injected:= true;
 end;
result:= CallNextHookEx(myHook, nCode, wParam, lParam);
end;

procedure Install;
var ProcId: Cardinal;
begin
ProcId:= GetWindowThreadProcessId(GethWnd, nil);
myHook:= SetWindowsHookEx(WH_GETMESSAGE, @myHookProc, hInstance, ProcId);
if myHook <> 0 then
 PostMessage(FindWindow(0, "Form1"), WM_USER + 100, 0, SUCCESS)
else
 PostMessage(FindWindow(0, "Form1"), WM_USER + 100, 0, FAILED);
end;

procedure Uninstall;
begin
UnHookWindowsHookEx(myHook);
end;

exports Install, Uninstall;

begin
end.


 
nomshar   (2004-09-29 18:38) [7]

Таким образом получается, что снимай, хук, не снимай, библиотека все равно не выгрузится - на нее есть ссылка в explorer.exe. Рихтер, к сожалению, о том, как можно выгрузить dll в таком случае ничего не говорит. Однако он привел (в своем четвертом издании) пример внедрения в чужой код. Но опять же, метод создан для внедрения в dll и только с подменой конкретной (известной функции; Рихтер подменял MessageBoxA). Здесь этот метод не подходит. Надо каким-то образом внедриться в код explorer.exe и на каком-то шаге его исполнения перевести управления на свою функцию, которая от его имени и выгрузит dll.
Кстати, по этому поводу родился вопрос. Преположим, я внедрил dll в процесс, запущенный с правами SYSTEM (пусть я таких прав не имею). Вопрос такой (вернее их два). 1. Процесс "А" внедряет dll в процесс "В". Процесс "А" имеет права ниже прав процесса "В". Возможно ли в этом случае внедрение.
2. Если внедрение возможно, то может ли процесс "А" посредством внедренной dll дать себе или еще кому права, аналогичные процессу "В"?


 
Cobalt ©   (2004-09-29 22:36) [8]

>Я так понял, ты имеешь в виду способ внедрения с двуями dll.
Нет, отчего же - с одной длл-кой.

что снимай, хук, не снимай, библиотека все равно не выгрузится - на нее есть ссылка в explorer.exe.
ты же сам загружаешь её -
if loadLibrary("injectdll.dll") <> 0 then
А вот без этой загрузки у тебя бы при снятии хука окно Проводника упало бы - потому что оконная процедура указывала бы на недействительную - выгруженную - память.

Так вот - тебе надо добавить такую вещь - что бы при постановке хука оконная процедура не заменяла "родную" на свою, а наоборот.

И рекомендуется пользоваться для хранения переменных в длл-ках с хуками в отображаемых в память файлах - посмотри статью здесь на сайте.

P.S. Сдаётся мне, откуда-то ты взял эту длл-ку ;)


 
Digitman ©   (2004-09-30 08:26) [9]


>  способ перехвата событий


не событий, а сообщений


>  Да его надо обязательно ставить из dll


не обязательно. зависит от типа хука.


> свою библиотеку внедряю в другой процесс


если ты ее внедряешь явно (т.е. не средствами установки глоб.хука), то это совершенно иной вопрос

myHook:= SetWindowsHookEx(WH_GETMESSAGE, @myHookProc, hInstance, ProcId);

уже здесь несуразица.
с параметрами.
обо всем остальном рассуждать смысла не имеет.

ты читал вообще справку к ф-ции ?


 
Cobalt ©   (2004-09-30 10:08) [10]

2 Digitman ©
Я же намекаю - взял он её откуда-то ;)
<offtopic>
Таки я был прав насчёт освобождения памяти под интерфейс?
</offtopic>


 
Digitman ©   (2004-09-30 10:10) [11]

содрал конечно ... причем совершенно бездумно


 
nomshar   (2004-09-30 19:34) [12]

> all. Народ, обижаете. Библиотека написана лично мной и не откуда я ее не сдирал. Это во-первых. Во-вторых, метод, которым я пользуюсь, очень хорошо описан у того же Рихтера. Идею, да, содрал (вернее перенял), но библиотеку своими руками писал. Даже обидно как-то. Сам написал, а тебе говорят, что содрал.

> Cobalt. Действительно explorer падает при попытке выгрузить библиотеку.


> Так вот - тебе надо добавить такую вещь - что бы при постановке
> хука оконная процедура не заменяла "родную" на свою, а наоборот.


Что ты имеешь в виду? Не подменять оконную процедуру. Тогда, скажи, как же я буду обрабатывать сообщения окна?


 
nomshar   (2004-09-30 19:46) [13]

> Digiman Слушай, меня, честно говоря, очень расстроило твое высказывание о якобы "бездумно содранной" библиотеки.
Dll написана на чистом WinAPI. Если это плагиат, что все, кто использует WinAPI плагиатчики. Далее. Ты Рихтера когда-нибудь читал?! А Руссиновича, а Шрайбера. Ты знаешь, они все используют WINAPI, все используют при подготовки своих проектов чужой код (исходники Windows, Руссинович в предисловии к книги прямо об этом заявляет). Они получается тоже "бездумно сдирают".
Прошу прощения за off-topic, просто не очень приятно слышать обвинения в плагиате, тем более от человека, который уже давно на форуме и, как я думал, является неплохим специалистом в своем деле. Еще раз извиняюсь за околопредметные сообщения.


 
Digitman ©   (2004-10-01 08:15) [14]


> nomshar


> околопредметные сообщения


душу отвел ?
теперь вернемся к нашим баранам ..

myHook:= SetWindowsHookEx(WH_GETMESSAGE, @myHookProc, hInstance, ProcId);

комментируй, что, для чего и почему именно так а не иначе ты передаешь в кач-ве параметров в вызов ф-ции

пока не разберешься досконально, дальше двигаться нет смысла


 
nomshar   (2004-10-01 16:27) [15]

> Digitman Все очень просто. Ставим хук на все сообщения (WH_GETMESSAGE), указываем адрес call-back функции.
ProcId - это уж, как ты понимаешь, идентификатор нужного нам процесса.
Что тебе не нравится в этой функции установки хука? Все довольно-таки логично.


 
Digitman ©   (2004-10-01 16:50) [16]


> ProcId - это уж, как ты понимаешь, идентификатор нужного
> нам процесса.


неверно.
параметр этот требует не идентификатор процесса, а идентификатор трэда

в действительности ты как раз и передаешь ид-р трэда, но почему он обзывается тобой ид-ром "процесса" ? процесс и трэд - две совершенно разные сущности ! и это наводит на мысль о полной твоей дезориентации  в объектах ОС ... подтверждение тому - явное указание тобой ненулевого параметра hInstance, хотя в справке черным по белому сказано, что глоб.хук требует указания hInstance при ThreadId = 0


 
Lin7   (2004-10-01 17:13) [17]

Мона я тоже подключюсь?  :)

> nomshar   (29.09.04 18:28) [6]

1.Переменная myHook должна быть в расшаренной области памяти. В таком варианте прога конечно не свалится, но так оччччччень не хорошо по отношению к другим прогам при работе под виндой ниже Win2000.

2.

> if loadLibrary("injectdll.dll") <> 0 then

Это зачем? Когда ставишь хук, твою dll в захученный процесс подгружает винда по SetWindowsHookEx и выгружает по UnHookWindowsHookEx тоже винда.

3. Если есть в dll string, то почему в uses нет ShareMem? ИМХО здесь можно избавиться от string"а.

4. Можно (и хорошо бы) избавиться от SysUtils и Classes в uses - dll будет значительно меньше. Правда прийдётся переписать пару функций.

Это может пригодиться  :)
http://www.delphimaster.ru/articles/hooks/index.html

Удачи.


 
Cobalt ©   (2004-10-01 23:22) [18]

2 nomshar
Значит так - приводи свой код в соответсвие с описанием по вышеприведённой статье - и выкладывай сюда - только тогда уже можно будет двигаться дальше, потому что то, что у Рихтера написано - оно использует особенности языка C, а в паскале такое не прокатит.

Ждём-с.


 
CherrY   (2004-10-04 09:57) [19]

Hi all!!!

2 Lin7:


> 1.Переменная myHook должна быть в расшаренной области памяти.
> В таком варианте прога конечно не свалится, но так оччччччень
> не хорошо по отношению к другим прогам при работе под виндой
> ниже Win2000.


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


> 2.
>
> > if loadLibrary("injectdll.dll") <> 0 then
>
> Это зачем? Когда ставишь хук, твою dll в захученный процесс
> подгружает винда по SetWindowsHookEx и выгружает по UnHookWindowsHookEx
> тоже винда.


Если внимательно посмотреть, то эта тема называется Dll injection, а это значит внедрение в чужой процесс.
Это делается для того, чтобы увеличить счётчик использования Dll.
Чтоб не свалить Explorer. И чтоб Dll которая внедрялась осталась в том процессе(Explorere) после закрытия основной программы.

Вопрос и от меня для всех...
Может nomshar не правильно Вам чтото отписал в вопросе, но меня тоже интересует вопрос возможности выгрузки Dll из чужого процесса, при наличии в нём моего кода.

Попытки FreeLibrary c хендлом данной Dll полученным GetModuleHandle с именем и с NULL ни к чему не привели.

Может чего то недопонимаю просветите.


 
nomshar   (2004-10-04 10:41) [20]

to all again. У меня складывается впечатление, что меня недопоняли. Я хочу внедрить dll в чужой процесс, это не банальная установка хука.
Теперь по ответам.

>Digiman.

> параметр этот требует не идентификатор процесса, а >идентификатор
> трэда


Согласен. Просто я так его обозвал, уж извини, запутал может быть.


> хотя в справке черным по белому сказано, что глоб.хук требует
> указания hInstance при ThreadId = 0


Обратимся к первоисточнику, то есть к MSDN.
SetWindowsHookEx Function
...
hMod
[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.

hMod должен быть нулевым, если dwThreadId указывает на поток созданный текущим процессом и если процедура хука ассоциирована с текущим процессом. А мы что делаем. Мы внедряем dll в другой процесс и соответственно явно указываем на поток процесса, передавая его id, найденный GetProcessThreadId, и передаем ссылку на нашу библиотеку.

Далее.


> Lin7


> Это зачем? Когда ставишь хук, твою dll в захученный процесс
> подгружает винда по SetWindowsHookEx и выгружает по >UnHookWindowsHookEx
> тоже винда.

Как зачем. Мы должны увеличить счетчик ссылок explorer.exe. Для этого мы и загружаем dll-ку саму в себя, так сказать.


> Переменная myHook должна быть в расшаренной области памяти.
> В таком варианте прога конечно не свалится, но так оччччччень
> не хорошо по отношению к другим прогам при работе под виндой
> ниже Win2000.

Согласен, правильней было бы и так. Но! Можно и оставить так как есть. Все нормально. Переменная myHook, как уже ранее указал Cherry, может измениться.


> Cobalt


> что у Рихтера написано - оно использует особенности языка
> C, а в паскале такое не прокатит.

Извини, но ты меня увидил. Рихтер в своих книгах иногда ссылается на библиотеку C от Microsoft, но в большей мере он использует WinAPI. И кто тебе мешает использовать функции WinAPI в приложениях, написанных на Delphi?!


 
Cobalt ©   (2004-10-05 00:35) [21]

Неее, это ты не понял - Рихтер использует особенность.. ну, в общем-то, не языка - это, наверное, относится к возможностям компилятора,  - объявление в ДЛЛ сегмента данных, которое является общим для образов этой dll во всех процессах. В Дельфях такое недоступно.

Ещё раз - почитай статью - и приведи в соответствие. Если хочешь, конечно, продолжать обсуждение твоей проблемы.


 
nomshar   (2004-10-05 10:41) [22]

Итак, друзья. По просьбам общественности я прочел указанную статью. Хорошая статья. А теперь поговорим о моей dll (попутно я буду ссылаться на некоторые фразы из статьи).
1.

>dwThreadID: данный параметр идентифицирует поток, с которым >будет связана ловушка. Мы ведём речь о глобальных ловушках, >поэтому данный параметр будет всегда равен 0, что означает, >что ловушка будет связана со всеми потоками в системе.

Это утверждение правильно только лишь в том случае, если мы хотим получать сообщения от всех процессов. Я же внедряю dll в конкретный процесс и мне нужны только сообщения от этого конкретного процесса, поэтому я и передаю в параметре dwThreadID идентификатор потока SysListView32.

2.

>Пусть в Process2 возникает событие на которое поставлена >ловушка, тогда Dll из первого процесса проецируется на АП >Process2, а данные DLL в Process2 инициализируются заново, и >получается, что в Process2 в переменной, в которой "лежал" >дескриптор поставленной ловушки в Process1, будет равен 0.


>Для того, что бы все экземпляры DLL, находящиеся в разных >процессах, имели доступ к дескриптору ловушки, надо выделить >какую-то область, доступ к которой будут иметь все "желающие".

Об этом по-подробнее. Согласен, при проецировании dll в чужое адресное пространство дескриптор хука теряется. Но я же делаю совсем иначе. Я работаю в одном процессе, создаю хук также в одном процессе, так что никакого обнуления данных не происходит. Так что мне нафиг не нужны файлы проецируемые в память.


 
Digitman ©   (2004-10-05 11:00) [23]


> nomshar


приведи цитату из документации MS, где явно сказано, что при указанных тобой ненулевых параметрах hInstance и dwThreadId образ хук-DLL будет проецироваться только в ВАП того процесса, который создал трэд с указанным тобой dwThreadId


 
Cobalt ©   (2004-10-05 11:41) [24]

hMod

Identifies the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.


2 nomshar
Будь так добр - прислушивайся к людям - статьи тут не лохи писали всё-таки.

Файл, проецируемый в память, тебе нужен для того, что бы идентификатор хука был актуален в АП "Проводника" - ты ведь должен вызывать следующие хуки в цепочке.
myHook:= SetWindowsHookEx ты делаешь в АП своей проги, а хук вызывается в АП "Проводника".

Это описано в статье - а ты не обратил внимание:

Наш Process1 устанавливает глобальную ловушку из DLL находящейся в адресном пространстве (АП) нашего процесса (Process1). DLL, находящаяся в АП процесса1 имеет свои данные, обозначенные на рисунке как Dll data. Когда система посылает событие, на которое мы установили ловушку, в Process2, то в Process2 отображается код DLL, находящийся в первом процессе (Dll code), НО НЕ ДАННЫЕ ! Все данные, только что отображённой в Process2 DLL, инициализируются заново (т.е. равны 0, nil, False в зависимости от типа). То есть, Process2 знать не знает о существовании Process1, и всё что в нём находится никак не относится к АП первого процесса, из которого произошло отображение кода DLL.

А вот адрес оконной процедуры, в принципе, можно хранить только в АП "Проводника" - т.е. локальной переменной длл-ки. Но это не красиво - не едино.


 
nomshar   (2004-10-05 14:14) [25]

По поводу цепочки хуков. Да, действительно MyHook равен нулю и цепочка хуков не вызывается.
Но по поводу проекции на все процессы:

Из Рихтера, глава 22, книга Создание эффективных win32 приложений...
"
Аргумент WH_GETMESSAGE определяет тип ловушки, а параметр GetMsgProc — адрес функции (в адресном пространстве Вашего процесса), которую система должна вызывать всякий раз, когда окно собирается обработать сообщение Параметр hinstDll идентифицирует DLL, содержащую функцию GetMsgProc В Windows значение htnstDll для DLL фактически задаст адрес в виртуальной памяти, по которому DLL спроецирована на адресное пространство процесса. И, наконец, последний аргумент, 0, указывает поток, для которого предназначена ловушка. Поток может вызвать SelWindowsHookEx и передать ей идентификатор другого потока в системе Передавая 0, мы сообщаем системе, что ставим ловушку для всех существующих в ней GUI-потоков

Теперь посмотрим, как все это действует:

1. Поток процесса В собирается направить сообщение какому-либо окну.

2. Система проверяет, не установлена ли для данного потока ловушка WH_GETMESSAGE.

3. Затем выясняет, спроецирована ли DLL, содержащая функцию GctMsgProc, на адресное пространство процесса В

4. Если указанная DLL еще не спроецирована, система отображает ее на адресное пространство процесса В и увеличивает счетчик блокировок (lock count) проекции DLL в процессе В на 1

5. Система проверяет, не совпадают ли значения hinstDll этой DLL, относящиеся к процессам А и В Если hinstD!l в обоих процессах одинаковы, то и адрес GetMsgProc в этих процессах тоже одинаков Тогда система может просто вызвать GetMsgProc в адресном пространстве процесса А. Если же hinstDll различны, система определяет адрес функции GetMsgProc в адресном пространстве процесса В по формуле:

GetMsgProc В = histDll В + (GetMsgProc А - hinstDll А)

Вычитая hinstDll из GetMsgProcA, Вы получаете смещение (в байтах) адреса функции GetMsgProc. Добавляя это смещение к hinstDll В, Вы получаете адрес GetMsgProc, соответствующий проекции DLL в адресном пространстве процесса В

6. Счетчик блокировок проекции DLL в процессе В увеличивается на 1.

7. Вызывается GetMsgProc в адресном пространстве процесса В.

8. После возврата из GetMsgProc счетчик блокировок проекции DLL в адресном пространстве процесса В уменьшается на 1.

Кстати, когда система внедряет или проецирует DLL, содержащую функцию фильтра ловушки, проецируется вся DLL, а не только эта функция. А значит, потокам, выполняемым в контексте процесса В, теперь доступны все функции такой DLL."

Итак. Библиотека загружается только при срабатываении нашего хука и после отработки процедуры хука счетчик использования dll уменьшается на один и она (библиотека) выгружается.
Может я что-то неправильно понимаю, то разъясните.


 
Digitman ©   (2004-10-05 15:16) [26]


> Библиотека загружается только при срабатываении нашего хука
>


..и загружается отдельным экз-ром в АП этого GUI-процесса


> после отработки процедуры хука счетчик использования dll
> уменьшается на один и она (библиотека) выгружается


нет, не выгружается
выгружена она будет в ходе исполнения UnhookWindowsHookEx

и вообще - ради внедрения в АП одного-единственного процесса неразумно ударяться в глоб.хуки, достаточно просто внедрить в АП этого процесса свою ДЛЛ (CreateRemoteThread) или, если процесс еще не существует, отслеживать его старт и по факту оного немедленно выполнить внедрение тем же CreateRemoteThread


 
nomshar   (2004-10-05 15:35) [27]


> Digitman



> и вообще - ради внедрения в АП одного-единственного процесса
> неразумно ударяться в глоб.хуки, достаточно просто внедрить
> в АП этого процесса свою ДЛЛ (CreateRemoteThread) или, если
> процесс еще не существует, отслеживать его старт и по факту
> оного немедленно выполнить внедрение тем же CreateRemoteThread

Согласен, только понимаешь, мне надо, чтобы мой процесс внедрил dll и его (мой процесс) можно было спокойно "убить", а внедренная библиотека спокойно работала. Поэтому меня и привлек метод с хуками и заменой оконной процедуры.


 
Digitman ©   (2004-10-05 15:47) [28]


> надо, чтобы мой процесс внедрил dll и его (мой процесс)
> можно было спокойно "убить", а внедренная библиотека спокойно
> работала


и что этому мешает ?
твой процесс выполнил CreateRemoteThread и преспокойно завершается

в ходе же исполнения тела удаленного трэда в "чужое" АП загружается твоя ДЛЛ и "живет" там хоть вплоть до завершения "чужого" процесса


 
nomshar   (2004-10-05 15:53) [29]

Кстати, по этой тематике на RSDN вышла очень хорошая статья:
http://www.rsdn.ru/article/?522


 
Cobalt ©   (2004-10-05 16:15) [30]

Да, получается, что адрес "старой" оконной процедуры тоже надо хранить в файле.

P.S. терпения моего не хватило, я больше писать сюда не буду.


 
Ertong ©   (2004-10-07 07:49) [31]

Я внедрял с помощью CreateRemoteThread.
Слудующий код самовыгружает DLL.

function thread(p:pointer):integer; stdcall;
begin
 {Делаем нашу работу}
 CreateThread(nil,0,GetProcAddress(GetModuleHandle("kernel32"),"FreeLibrary"),pointer(hInstance),0,id);
end;
begin
 HThread:=CreateThread(nil,0,@Thread,nil,0,ThreadID);
end.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.59 MB
Время: 0.034 c
4-1096885733
drew
2004-10-04 14:28
2004.11.14
Удаление значения ключа из реестра


3-1098039899
S@shka
2004-10-17 23:04
2004.11.14
100% загрузка проца


3-1097840430
diabolik_krsk
2004-10-15 15:40
2004.11.14
Создание колонок DBGrid а во время прогона программы


9-1090363698
Profi
2004-07-21 02:48
2004.11.14
DirectDraw


1-1098961605
Chlavik
2004-10-28 15:06
2004.11.14
Pointer -> _ContactItem и наоборот





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский