На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
  
> А можно ли найти окно по имени процесса , Наоборот можно, а вот так?
    У окна которое я ищу постоянно меняется название, можно конечно поискать по той части названия которая неизменна. Но а если такой части нет, ведь если по окну можно найти процесс то наверное и обратно тоже можно... Хотя процесс может иметь несколько окон, но в любом случае среди них найти будет проще.
      Daemon, можно по имени класса искать.
        Krid, можно, знать бы ещё по какому
        Сообщение отредактировано: Daemon -
          ээээ... а какие вообще есть критерии, по которым можно отличить именно это окно от других? Имя проги (exe'шник)? Тогда чем оно отличается от остальных окон процесса?
            Цитата Daemon @
            можно, знать бы ещё по какому


            Ставишь курсор над этим окном и выполняешь такой код:

            ExpandedWrap disabled
              procedure TForm2.Timer1Timer(Sender: TObject);
              var
                H: HWND;
                P: TPoint;
                Buff: array [0..255] of Char;
              begin
                GetCursorPos(P);
                H := WindowFromPoint(P);
                GetClassName(H, Buff, SizeOf(Buff));
                Memo1.Lines.Add(String(Buff));
              end;
              Rouse_, это не самый удобный и немного напрягающий метод. Мне нужнна полная автоматизация.

              Krid, есть exe-шник и знание того что окно 'главное'. На самом деле если без заморочек нельзя то и ... с ним.

              И ещё вопрос в продолжение темы. Предположим окно я нашёл, а как можно отлавливать изменения происходящие с ним (изменение размера например или потерю фокуса)? И ещё, можно ли определить осталось ли окно видимым после потери фокуса, точнее даже не всё окно а его определённая часть?

              Фактически надо получить окно липучку
              Сообщение отредактировано: Daemon -
                Цитата Daemon @
                это не самый удобный и немного напрягающий метод

                Это самый простой метод помогающий узнать класс окна. Он же у тебя не будет изменяться.
                Соответственно, при помощи него определи класс окна (как я показал), а потом как и сказал Krid, ищешь окно по имени класса и делай с ним все что тебе необходимо.


                Цитата Daemon @
                а как можно отлавливать изменения происходящие с ним (изменение размера например или потерю фокуса)?

                Ну тут уже придется внедрять свой код в адресное пространство процесса в котором отображается это окно (к примеру хуком - самое универсальное) и там перехватывать все события адресованые этому окну.
                  Цитата Rouse_ @
                  Это самый простой метод помогающий узнать класс окна. Он же у тебя не будет изменяться.
                  Соответственно, при помощи него определи класс окна (как я показал), а потом как и сказал Krid, ищешь окно по имени класса и делай с ним все что тебе необходимо.

                  Хм... да действительно, грамотно.


                  Цитата Rouse_ @
                  Ну тут уже придется внедрять свой код в адресное пространство процесса в котором отображается это окно (к примеру хуком - самое универсальное) и там перехватывать все события адресованые этому окну.

                  УУУ, а где нить пример нарыть можно...? А то я даже толком не понимаю чего искать надо :D :wall:
                    Daemon, послушай Rouse_'а. Тебе нужно только 1 раз узнать имя класса окна. Дальше ты его зашьешь в прогу (как и имя exe'шника) и все.

                    Ну, если очень хочется поизвращаться, можно примерно так:
                    ExpandedWrap disabled
                      const
                       exeName = 'MYPROG.EXE';
                       
                      var
                       fWnd:hwnd;
                       
                       
                      function GetModuleFileNameExW(hProcess:THandle; hModule:HMODULE; lpFilename:PWideChar; nSize:DWORD):DWORD; stdcall; external 'PSAPI.DLL'
                       
                      function WindowGetEXE(wnd:HWND):string; // для Win2K/XP. В Win9x нужно юзать GetWindowModuleFileName
                      var
                       wt:array[0..MAX_PATH-1] of WChar;
                       prc:THandle;
                       prcID:cardinal;
                      begin
                       result:='';
                       if GetWindowThreadProcessID(wnd,prcID)<>0 then
                       begin
                        prc:=OpenProcess(PROCESS_ALL_ACCESS,false,prcID);
                        if prc<>0 then
                        try
                          if GetModuleFileNameExW(prc,0,wt,MAX_PATH*2)<>0 then result:=wt
                        finally
                         CloseHandle(prc)
                        end
                       end
                      end;
                       
                      function EnumWindowsProc(wnd:HWND; lParam: LPARAM):BOOL; stdcall;
                      begin
                       result:=true;
                       if IsWindowVisible(wnd) and (GetParent(wnd)=0) and
                       (wnd<>Application.Handle) and (wnd<>Form1.Handle) // проверка, что окно не твое собственное.
                       and
                       (UpperCase(ExtractFileName(WindowGetEXE(wnd)))=exeName) then
                       begin
                         fWnd:=wnd;
                         result:=false
                       end
                      end;
                       
                      procedure TForm1.Button1Click(Sender: TObject);
                      begin
                       fWnd:=0;
                       EnumWindows(@EnumWindowsProc,0);
                       if fWnd=0 then ShowMessage('Not found') else ShowMessage('Found window '+IntToStr(fWnd))
                      end;

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

                    Добавлено
                    с небольшим опозданием :)
                      Цитата Daemon @
                      УУУ, а где нить пример нарыть можно...?

                      Посмотрю, гдето у меня дома валялся пример с определением процессов с таймером. Там примерно такойже принцип использовался...
                        Цитата Daemon @
                        А то я даже толком не понимаю чего искать надо

                        DLL injecting и subclassing
                          Цитата Krid @
                          Лучше всего узнать имя класса.

                          С именем класса тоже не всё гладко, дело в том что на данный момент с текущей версией программы всё работает, а какие имена были у старых версий и что будет с новыми неизвестно. Поэтому я и хотел привязаться к имени exe-шника ибо он всегда тот же.

                          Добавлено
                          Цитата Rouse_ @
                          Посмотрю, гдето у меня дома валялся пример с определением процессов с таймером. Там примерно такойже принцип использовался...

                          Жду и надеюсь :D
                            Daemon, еще можешь попробовать например ToolHelp. Получаешь ID процесса и внедряешься в него CreateRemoteThread'ом. Но это только для Win2K+. Можешь мой код (или подобный какой-нить) юзать и внедряться с помощью ловушек (и Win9x и Win2K+).
                            Ну а после внедрения - subclassing (замена чужой оконной процедуры на свою, перехват сообщений).

                            Добавлено
                            Да, а про внедрение Рихтера почитай (если не читал еще). 22-ю главу.
                              Вот тебе пример внедрения:

                              ExpandedWrap disabled
                                function SetDebugPriv: Boolean;
                                var
                                  Token: THandle;
                                  tkp: TTokenPrivileges;
                                begin
                                  Result := false;
                                  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
                                  begin
                                    if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'), tkp.Privileges[0].Luid) then
                                    begin
                                      tkp.PrivilegeCount := 1;
                                      tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
                                      Result := AdjustTokenPrivileges(Token, false, tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^);
                                    end;
                                  end;
                                end;
                                 
                                function TfrmMain.InjectLib(const ProcessID: DWORD): Boolean;
                                var
                                  Process: HWND;
                                  ThreadRtn: FARPROC;
                                  DllPath: String;
                                  RemoteDll: Pointer;
                                  BytesWriten: DWORD;
                                  Thread: DWORD;
                                  ThreadId: DWORD;
                                  ExitCode: DWORD;
                                begin
                                  // Устанавливаем отладочные привилегии для нашего процесса
                                  Result := SetDebugPriv;
                                  if not Result then Exit;
                                  Process := 0;
                                  Thread := 0;
                                  try
                                    // Открываем процесс
                                    Process := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or
                                      PROCESS_VM_WRITE, True, ProcessID);
                                    if Process = 0 then Exit;
                                    // Выделяем в нем память под строку
                                    DllPath := ExtractFilePath(ParamStr(0)) + 'hooklib.dll';
                                    RemoteDll := VirtualAllocEx(Process, nil, Length(DllPath),
                                      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
                                    if RemoteDll = nil then Exit;
                                    // Пишем путь к длл в его адресное пространство
                                    if not WriteProcessMemory(Process, RemoteDll, PChar(DllPath),
                                      Length(DllPath), BytesWriten) then Exit;
                                    if BytesWriten <> DWORD(Length(DllPath)) then Exit;
                                    // Получаем адрес функции в Kernel32.dll
                                    ThreadRtn := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'LoadLibraryA');
                                    if ThreadRtn = nil then Exit;
                                    // Запускаем удаленный поток
                                    Thread := CreateRemoteThread(Process, nil, 0, ThreadRtn, RemoteDll, 0, ThreadId);
                                    if Thread = 0 then Exit;
                                    // Ждем пока удаленный поток отработает...
                                    if (WaitForSingleObject(Thread, INFINITE) = WAIT_OBJECT_0) then
                                      if GetExitCodeThread(Thread, ExitCode) then
                                        Result := ExitCode = 0;
                                  finally
                                    // Удаленный поток свою задачу выполнил и загрузил нашу библиотеку,
                                    // можно освобождать занятую память...
                                    if RemoteDll <> nil then
                                      VirtualFreeEx(Process, @RemoteDll, 0, MEM_RELEASE);
                                    if Thread <> 0 then CloseHandle(Thread);
                                    if Process <> 0 then CloseHandle(Process);
                                  end;
                                end;


                              Пример использования:

                              ExpandedWrap disabled
                                    if InjectLib(GetCurrentProcessID{или PID открытого процесса}) then
                                      lbStatus.Items.Add('Library injected succes.')
                                    else
                                      lbStatus.Items.Add('Library injected fail.')


                              Соответственно, пиши свою библиотеку, которая при загрузке делает сабклассинг, потом ищи нужное окно, получай PID процесса GetWindowThreadProcessId, и выполняй данный код...

                              Вот так вот в кратце... :)
                                Хехе :wall:
                                Думаю завтра у меня появится много вопросов... :D
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0483 ]   [ 16 queries used ]   [ Generated: 19.04.24, 07:54 GMT ]