На главную Наши проекты:
Журнал   ·   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
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Как узнать процесс родителя. , нужно для плагина...
    Господа вопрос такой. Есть процесс.
    Как узнать процесс родителя.
    Тоесть узнать имя процесса запустившего мою программу.

    Хотел написать плагин для Internet explorer'а, где если бы программа запускалась с параметром -d то сразу программа определяла что программу запустил Internet explorer,ан нет оказываеться нет. Там в ветви Software\Microsoft\Internet Explorer\Extensions, добавляються программы на исполнение, без дополнительных параметров, то есть не гибкий однако Internet explorer.

    Вопрос: Может есть у кого наработки на узнавание родителя процесса.

    Спросите вы, что мне лень. Да нет с TlHelp32 работал, просто чьйто наработки могут быть полезны для меня, и для других, кто дальше столкнеться с данной проблемой...

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

      Цитата SOLON7 @
      то есть не гибкий однако Internet explorer

      Да что вы говорите, с каких это пор динамические библиотеки (DLL) стали запускаться с параметрами коммандной строки?

      Добавлено
      Где в LoadLibrary вы увидели параметры коммандной строки?
        Ничего не поняла насчет "плагин для Internet explorer'а" и "не гибкости Internet explorer" :)
        Посему, попробую ответить на "Тоесть узнать имя процесса запустившего мою программу."
        Раз любишь задачки, то вот для затравки набросала ф-ию поиска ID родителя:
        (не тестировала)
        ExpandedWrap disabled
          function GetMyParentID(var ParentID: DWord): DWord;
          var
           ProcEntry: TProcessEntry32;
           hSnapshot: THandle;
           CurrID: DWord;
           _OK: Boolean;
          begin
           hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
           if hSnapshot <> INVALID_HANDLE_VALUE then
            try
             ProcEntry.dwSize := SizeOf(ProcEntry);
             _OK := Process32First(hSnapshot, ProcEntry);
             if _OK then
              begin
               CurrID := GetCurrentProcessId;
               SetLastError(ERROR_SUCCESS);
               while _OK do
                if ProcEntry.th32ProcessID = CurrID then
                 begin
                  ParentID := ProcEntry.th32ParentProcessID;
                  Break;
                 end
                else _OK := Process32Next(hSnapshot, ProcEntry);
              end;
             Result := GetLastError;
            finally
             CloseHandle(hSnapshot);
            end
           else Result := GetLastError;
          end;

        Ну а чуть-чуть ее видоизменить для нахождения имени родителя по его ID
        оставляю в качестве домашего задания :)

        P.S.
        Только проку от данной методики, как от козла молока.
        Процесса родителя уже может и не быть в помине, пока мы тут соизволяем его искать :)
        И полученный нами ID, можно выбрасывать на помойку.

        Гораздо лучше использовать NtQuerySystemInformation с
        параметром SystemProcessesAndThreadsInformation - можно обойтись одним "снимком".
        Правда и с CreateToolhelp32Snapshot можно, но придется запоминать ProcEntry`ы.

        P.S.S.
        >Да нет с TlHelp32 работал
        >Я люблю, когда появляються задачи по программированию..
        >Но тут немного в невиддении насчет родителя..
        Ой как "не вяжутся" эти три фразы :)
        (особенно учитывая, что в Help`е есть пример :)

        Забыла еще одну неприятную вещь:
        Может получиться так, что к моменту нашего поиска, родитель уже умрет,
        и будет создан другой процесс с такм же ID, как и у родителя.
        А вот чтобы не попасть впросак с этим, придется использовать NtQuerySystemInformation
        и сравнивать времена создания найденого нами родителя и наше.
        Сообщение отредактировано: Riply -
          Цитата Riply @
          Забыла еще одну неприятную вещь:
          Может получиться так, что к моменту нашего поиска, родитель уже умрет,
          и будет создан другой процесс с такм же ID, как и у родителя.


          Да вы что, а разве PID не растет с каждым новым запуском нового процесса, как-то не вяжется, чтобы PID был одинаков у процессов, это было по крайне мере глупо со стороны MICROSOFT делать такое.
          Процесса может быть уже убит, но чтобы pid были одинаковы не вериться...

          Добавлено
          Я нашел пожалуй самый легкий метод определения, как узнавать запущенна ли прога из интернет експлорер.

          При запуске из ИНтернет Експолера не передаеться параметр "Рабочий каталог". То есть можно проверить если рабочий каталог неравен Extractfilepath(paramstr(0)) то значит его запустил ИНтернет Експолера. Да твик не гибкий, но простой и не требующих мозломства.

          RIPLY, а вы что преподователь, изложили все в такой форме, красиво. Мне кажеться вы преподователь, или по крайне мере имеете его задатки...

          ВСЕМ СПАСИБО ПЛАН РАБОТЫ НАМЕЧЕН, БУДЕМ РАБОТАТАТЬ.
            Цитата SOLON7 @
            Да вы что, а разве PID не растет с каждым новым запуском нового процесса

            Нет. В общем случае это не так.
            Цитата SOLON7 @
            как-то не вяжется, чтобы PID был одинаков у процессов

            У двух процессов, существовавших одновременно в некий момент времени, одинаковых ID быть не может.
            Но эта ситуация вполне реальна, для процессов, разнесенных во времени.
            Кстати, вероятность этого не так уж мала, как кажется.
            Цитата SOLON7 @
            Я нашел пожалуй самый легкий метод определения, как узнавать запущенна ли прога из интернет експлорер.
            При запуске из ИНтернет Експолера не передаеться параметр "Рабочий каталог". То есть можно проверить если рабочий каталог неравен Extractfilepath(paramstr(0)) то значит его запустил ИНтернет Експолера

            Этот способ определения череват ошибками, imho. Ибо из факта "если рабочий каталог неравен Extractfilepath(paramstr(0))"
            отнюдь не следует, что нас запустил IE. :)
              Цитата
              Да вы что, а разве PID не растет с каждым новым запуском нового процесса, как-то не вяжется, чтобы PID был одинаков у процессов


              Riply абсолютно права. Я к сожелению не смог найти прямого ответа в MSDN, там весьма уклончиво отвечают на этот вопрос - "The identifier is valid from the time the process is created until the process has been terminated." Эту фразу, в принципе, можно понять по разному. Зато недвусмысленно это описано у Рихтера, так что сошлемся на его авторитет:

              Подчеркну ещс один чрезвычайно важный момент система способна повторно использовать идентификаторы процессов и потоков. Например, при создании про цесса система формирует объект "процесс", присваивая ему идентификатор со зна чением, допустим, 122 Создавая новый объект "процесс", система уже не присвоит ему данный идентификатор. Но после выгрузки из памяти первого объекта следу ющему создаваемому объекту "процесс" может быть присвоен тот же идентификатор — 122.

              Эту особенность нужно учитывать при написании кода, избегая ссылок на невер ный объект "процесс" (или "поток"). Действительно, затребовать и сохранить иден тификатор процесса несложно, но задумайтесь, что получится, ссли в следующий момент этот процесс будет завершен, а новый получит тот же идентификатор: сохра ненный ранее идентификатор уже связан совсем с другим процессом.
                Узнать родителя любого процесса можно и без перебора процессов в снимке. Например вот так:

                ExpandedWrap disabled
                  type
                    PROCESS_BASIC_INFORMATION = packed record
                      ExitStatus: DWORD;
                      PebBaseAddress: Pointer;
                      AffinityMask: DWORD;
                      BasePriority: DWORD;
                      uUniqueProcessId: Ulong;
                      uInheritedFromUniqueProcessId: Ulong;
                    end;
                   
                  function  NtQueryInformationProcess(
                      ProcessHandle : THandle;
                      ProcessInformationClass : Byte;
                      ProcessInformation : Pointer;
                      ProcessInformationLength : ULONG;
                      ReturnLength : PULONG
                    ): DWORD; stdcall; external 'ntdll.dll';
                   
                  function GetOwnedProcessID(const dwProcessHandle: DWORD): DWORD;
                  const
                    ProcessBasicInformation = 0;
                  var
                    Info: PROCESS_BASIC_INFORMATION;
                  begin
                    Result := 0;
                    if NtQueryInformationProcess(dwProcessHandle,
                      ProcessBasicInformation, @Info, SizeOf(Info), nil) = NO_ERROR then
                      Result := Info.uInheritedFromUniqueProcessId;
                  end;


                Вот так будет выглядеть получение родителя от текущего процесса:

                ExpandedWrap disabled
                  procedure TForm1.Button1Click(Sender: TObject);
                  var
                    dwProcessHandle: DWORD;
                  begin
                    DuplicateHandle(GetCurrentProcess, GetCurrentProcess, GetCurrentProcess,
                      @dwProcessHandle, 0, False, DUPLICATE_SAME_ACCESS);
                    Caption := IntToStr(GetOwnedProcessID(dwProcessHandle));
                  end;
                  Rouse_

                  DuplicateHandle не обязательно. NtQueryInformationProcess прекрасно съедает и псевдохэндл.
                    Rose, согласен...
                      Цитата Rouse_ @
                      Узнать родителя любого процесса можно и без перебора процессов в снимке. Например вот так:

                      А мы не привыкли искать легкие пути :)
                      А если серьезно, то мне это просто не пришло в голову.
                      Спасибо.
                        НУ родителя мы то узнаем, а как узнать является ли процесс Internet Explorer....
                          GetModuleFileNameEx очевидно :)
                            А какой же быстрый способ узнать по ПИДУ имя процесса.
                            Какую функцию по обьему кода посоветуете????
                            Чтоб поменьше кода было....
                              Тэкссс... тебе уже много насоветовали. Давай сначала посмотрим, понял ли ты все это. Выкладывай аттачем код, с которым сейчас эксперементируешь...
                                Вобщем если я правильно понял автору нужно что-то врое этого:
                                ExpandedWrap disabled
                                  const
                                    ProcessBasicInformation = 0;
                                    CSIDL_PROGRAM_FILES = $0026;
                                    IExplorePath: string = '\Internet Explorer\IEXPLORE.EXE';
                                   
                                  type
                                    PROCESS_BASIC_INFORMATION = packed record
                                      ExitStatus: DWORD;
                                      PebBaseAddress: Pointer;
                                      AffinityMask: DWORD;
                                      BasePriority: DWORD;
                                      uUniqueProcessId: Ulong;
                                      uInheritedFromUniqueProcessId: Ulong;
                                    end;
                                   
                                  function  NtQueryInformationProcess(
                                    ProcessHandle : THandle;
                                    ProcessInformationClass : Byte;
                                    ProcessInformation : Pointer;
                                    ProcessInformationLength : ULONG;
                                    ReturnLength : PULONG
                                    ): DWORD; stdcall; external 'ntdll.dll';
                                   
                                  function GetModuleFileNameExA(
                                    hProcess: DWORD;
                                    hModule: DWORD;
                                    lpFilename: PAnsiChar;
                                    nSize: DWORD
                                    ): DWORD; stdcall; external 'PSAPI.dll';
                                   
                                   
                                  function OwnerProcessIs_IExplore: Boolean;
                                  var
                                    lInfo: PROCESS_BASIC_INFORMATION;
                                    lParentProcHandle: THandle;
                                    lpFileName, lPFPath: PAnsiChar;
                                   
                                    dwProcessHandle: DWORD;
                                  begin
                                    Result := False;
                                    ZeroMemory(@lInfo, SizeOf(PROCESS_BASIC_INFORMATION));
                                   
                                    DuplicateHandle(GetCurrentProcess, GetCurrentProcess, GetCurrentProcess,
                                      @dwProcessHandle, 0, False, DUPLICATE_SAME_ACCESS);
                                   
                                    if NtQueryInformationProcess(dwProcessHandle, ProcessBasicInformation,
                                      @lInfo, SizeOf(PROCESS_BASIC_INFORMATION), nil) = NO_ERROR then
                                    begin
                                      lParentProcHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
                                         False, lInfo.uInheritedFromUniqueProcessId);
                                      if lParentProcHandle > 0 then
                                      begin
                                        lpFileName := GetMemory(MAX_PATH);
                                        ZeroMemory(lpFileName, MAX_PATH);
                                        lPFPath := GetMemory(MAX_PATH);
                                        ZeroMemory(lPFPath, MAX_PATH);
                                   
                                        if SHGetSpecialFolderPath(0, lPFPath, CSIDL_PROGRAM_FILES, False) and
                                          (GetModuleFileNameExA(lParentProcHandle, 0, lpFileName, MAX_PATH) > 0) then
                                          Result := lPFPath + IExplorePath = lpFileName;
                                        FreeMemory(lpFileName);
                                        FreeMemory(lPFPath);
                                      end;
                                      CloseHandle(lParentProcHandle);
                                    end;
                                    CloseHandle(dwProcessHandle);
                                  end;


                                Добавлено
                                Цитата

                                DuplicateHandle не обязательно. NtQueryInformationProcess прекрасно съедает и псевдохэндл.

                                Кстати пока отлаживал, псевдохендл не всегда отрабатывал(закономерности не понял), и NtQueryInformationProcess выкидывало с "неверный декриптор". Пришлось DublicateHandle все-таки оставить.
                                Сообщение отредактировано: Rennigth -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,2525 ]   [ 16 queries used ]   [ Generated: 25.04.24, 01:59 GMT ]