Re[3]: Получить ProcessID, имея hProcess?
От: Andrew S Россия http://alchemy-lab.com
Дата: 01.09.03 15:28
Оценка: 19 (2)
Думается, это слишком сложно. В 9х, как утверждает MATT PIETREK, все гораздо проще. Первое, что надо помнить — процесс ID в 9х — это всего лишь некоторое обратимое преобразование указателя на PDB процесса (xor with "Obsfucator" DWORD). Т.к. PDB находятся в shared memory, то pid гарантированно уникальны. Второе — то, что PDB текущего процесса можно получить некоторым образом (см. пример к главе 3 — у меня в электронной книге, к сожалению, эта часть отсутствует). Получая PDB, мы можем определить таблицу хендлов, по таблице хандлов можем получить указатель на PDB нужного нам процесса, а из него, используя пресловутое преобразование (1) получить искомый PID процесса.
Вот, примерно так.

ST>>Предлагаю свой изощренный способ (навеяно статьей в RSDN о перехвате API):


БП>Точно! В Win9x можно сделать xCreateRemoteThread(GetCurrentProcessId()).

БП>Павел.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Получить ProcessID, имея hProcess?
От: vasketsov Россия http://ntprog.by.ru
Дата: 03.09.03 04:32
Оценка: 14 (1)
Здравствуйте, Аноним, Вы писали:

А>>>Чего то я не понял. Почему OpenProcess не заюзать?

А>>>Передаешь туда PID и сравниваешь хэндлы.
А>А если так:
А хоть как.
OpenProcess создает НОВЫЙ хэндл.
А хэндлы по своей природе не сравниваются друг с другом.
Аналогия — утверждение навернства 2-х дверей, если у этих дверей одинаковые ручки.
К тому же, если первый хэндл был валиден в Вашем ВАП, то OpenProcess НИКОГДА не вернет аналогичную величину, потка тот хэндл не будет закрыт, так как нумерация хэндлов для одного процесса сквозная независимо от их типа (процесс, поток, файл, событие и т.д.).
Васкецов Сергей
http://registry.km.ru
Re[4]: Получить ProcessID, имея hProcess?
От: Sergey Ten http://www.fastalgo.com
Дата: 01.09.03 14:23
Оценка: 7 (1)
Здравствуйте, EM, Вы писали:

EM>
БП>>Точно! В Win9x можно сделать xCreateRemoteThread(GetCurrentProcessId()).
БП>>Павел.
EM>


EM>Как раз в Win9x — то и нельзя — CreateRemoteThread() есть только в NT/2000/XP


Имелось в виду вот это:

http://help.madshi.net/CreateRemoteThread.htm
Re[2]: Получить ProcessID, имея hProcess?
От: Sergey Ten http://www.fastalgo.com
Дата: 03.09.03 04:01
Оценка: 7 (1)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, LeonV, Вы писали:


LV>>Как можно получить PID, если есть hProcess?


А>Чего то я не понял. Почему OpenProcess не заюзать?

А>Передаешь туда PID и сравниваешь хэндлы.

OpenProcess вернет другой хэндл каждый раз про открытии того же самого процесса:


#include <windows.h>

main()
{
int i;

    for (i = 0; i < 10; i++)
        printf("process handle: %d\n", 
            OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()));
}


process handle: 2024
process handle: 2036
process handle: 2012
process handle: 2008
process handle: 2004
process handle: 2000
process handle: 1996
process handle: 1992
process handle: 1988
process handle: 1984

Re[3]: Получить ProcessID, имея hProcess?
От: EM Великобритания  
Дата: 01.09.03 14:04
Оценка: -1
БП>Точно! В Win9x можно сделать xCreateRemoteThread(GetCurrentProcessId()).
БП>Павел.


Как раз в Win9x — то и нельзя — CreateRemoteThread() есть только в NT/2000/XP
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re[4]: Получить ProcessID, имея hProcess?
От: Leonid Troyanovsky  
Дата: 02.09.03 17:26
Оценка: -1
Здравствуйте, Andrew S, Вы писали:

AS>Гм. Насколько я понимаю, имеется ввиду это:


AS>
AS>var
AS>  hProcess, hThread: THandle;
AS>  pGetCurrentProcessID: Pointer;
AS>  rtid, pid: DWord;
AS>..  
AS>  pGetCurrentProcessID := GetProcAddress( GetModuleHandle('kernel32.dll'), 
AS>       'GetCurrentProcessId');
AS>  Win32Check(pGetCurrentProcessID <> nil);
AS>  hThread:= CreateRemoteThread ( hProcess, 
AS>                                 nil,
AS>                                 0,
AS>                                 pGetCurrentProcessID,
AS>                                 nil,
AS>                                 0,
AS>                                 rtid);
AS>  Win32Check(hThread <> 0);
AS>  WaitForSingleObject(hThread, INFINITE);
AS>  GetExitCodeThread(hThread, pid);
AS>  CloseHandle(hThread);

AS>  Caption := IntToStr(pid); // result
AS>


Точно, оно.

AS>Итак, посмотрим определение функций


AS>
AS>//  то, что должно выступать в качестве функции треда:
AS>DWORD WINAPI ThreadProc(
AS>  LPVOID lpParameter   // thread data
AS>);

AS>//  То, что мы ему передаем.
AS>DWORD WINAPI GetCurrentProcessId(VOID);
AS>


При вызове функций, описанных прототипами реализуется вариант неявного
преобразования типов. По-настоящему важным является лишь физический размер
возвращаемого результата. К нашей радости(?) функции Win32 API в основном
возвращают (да и принимают четырехбайтовые) значения.
Вопрос же их интерпретации — целиком на совести использующего.

AS>Соглашение о передаче параметров winapi предусматривает то, что вызываемая функция очищает стек параметров. Таким образом, мы получаем на выходе из функции неправильный стек.


А чем оно отличается от вызыва твоей ThreadFunc, которой также передается
параметр — адрес структуры InjectInfo?

Да и чего ему портиться, если послетовательность CRT и GCPI имеют одно
и тоже соглашение о вызове.
Ну, а верность этих теоретических воззрений легко опровергнуть отладчиком.

IMHO, действительной проблемой является подобный вызов в случае, когда
параметров более одного.
Тогда, действительно есть нужда в ручном формировании стека и копировании
тела функции в чужой процесс по методу Джефа Рихтера, или с помощью
более прозрачной техники by Prasad Dubak, описанной ранее тобой.

AS>И в любом случае — этот метод не решает проблемы с 9х системами.В общем, лучше, правильнее и быстрее использовать в случае winnt (Nt/Zw)QueryInformationProcess.


Это временная проблема, бо 9х системы обречены на скорое вымирание
Ну, и в любом случае, Nt/ZwQueryInformationProcess не смогут ее решить

--
С уважением, LVT.
--
С уважением, LVT
Re[5]: Получить ProcessID, имея hProcess?
От: Andrew S Россия http://alchemy-lab.com
Дата: 02.09.03 20:08
Оценка: +1
По порядку.

1. Я не описывал никаких приемов формирования стека функции. Вы меня с кем-то путаете
2. По поводу 9х — смотрите ветку, решение там приведено.
3. По поводу NT тоже. И оно правильное, в отличие от этого.
4. Последнее, и самое главное — см. ниже:


AS>>Итак, посмотрим определение функций


AS>>
AS>>//  то, что должно выступать в качестве функции треда:
AS>>DWORD WINAPI ThreadProc(
AS>>  LPVOID lpParameter   // thread data
AS>>);

AS>>//  То, что мы ему передаем.
AS>>DWORD WINAPI GetCurrentProcessId(VOID);
AS>>


LT> При вызове функций, описанных прототипами реализуется вариант неявного

LT> преобразования типов. По-настоящему важным является лишь физический размер
LT> возвращаемого результата. К нашей радости(?) функции Win32 API в основном
LT> возвращают (да и принимают четырехбайтовые) значения.
LT> Вопрос же их интерпретации — целиком на совести использующего.

LT> А чем оно отличается от вызыва твоей ThreadFunc, которой также передается параметр — адрес структуры InjectInfo?


При вызове функций главным является соглашение о вызове (в данном случае обе winapi) и количество параметров, которые они в себя принимают. ThreadProc принимает 1 параметр (eq 4 байта на стеке), GetCurrentProcessId принимает 0 параметров. Итак, что происходит. Caller делает перед вызовом ThreadProc push lpParameter, ожидая, что по возвращению, ThreadProc вернет результат в eax и очистит стек (например, ret 2). Однако, GetCurrentProcessId этого не делает (просто ret), хотя и возвращает результат в eax. Итого — внешне все ОК, хотя на самом деле далеко не так — портится caller's стек.
И теперь — самое главное. MSDN:

process can obtain the return value of the ThreadProc of a thread it created with CreateThread by calling the GetExitCodeThread function. A process cannot obtain the return value from the ThreadProc of a thread it created with CreateRemoteThread.

http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Получить ProcessID, имея hProcess?
От: Аноним  
Дата: 03.09.03 02:19
Оценка: -1
Здравствуйте, LeonV, Вы писали:

LV>Как можно получить PID, если есть hProcess? Ситуация такова: стартует приложение через ShellExecuteEx. Что это за приложение — заранее неизвестно, так как в ShellExecuteEx я передаю путь к файлу, который требуется открыть.


LV>Далее необходимо послать сообщение окну того приложения, которое запустилось для открытия этого файла. После запуска процесса я делаю EnumWindows, а в функции EnumWindowsProc получаю PID процесса, в котором каждое окошко создано — GetWindowThreadProcessId. Один из этих PID — тот, который запустила ShellExecuteEx. По идее, их надо бы сравнить, но у меня на выходе ShellExecuteEx есть hProcess, а не пид. Как быть? Единственный способ узнать пид запущенного процесса, как я понял — вызвать CreateProcess и пид будет возвращен в структуре PROCESS_INFORMATION.


LV>Кто поможет?


<поскипано>

Чего то я не понял. Почему OpenProcess не заюзать?
Передаешь туда PID и сравниваешь хэндлы.
Re[8]: Получить ProcessID, имея hProcess?
От: Leonid Troyanovsky  
Дата: 03.09.03 07:46
Оценка: -1
Здравствуйте, Andrew S, Вы писали:

AS>Caller — это то, что вызывает функцию потока. Она же не сама по себе вызывается, верно?


Не сам по себе. Но, по поводу того как формируется стек нового потока-
это всего лишь домыслы (мои, твои). Посмотри отладчиком, если интересно.

AS>Тем более, что по выходу из потока код возврата сохраняется в TDB.


Ну, а в чем тут "более"? Это уже ближе к той цитате из MSDN,
не доверяющей возвращаемому значению.

LT>> Если бы было так, как ты описываешь, то удаленному потоку никогда и не удалось

LT>> воспользоваться полученным параметром. По-крайней мере, поток вызывал бы
LT>> AV по выходу из функции.

AS>А кто сказал, что он этого не делает? Вы можете достоверно это определить на всех системах линейки NT + то, что это происходит в другом процессе?


Необработанные исключения в процессе вызывают его завершение.
Это я знаю про все win32

AS> Еще раз. Вам указан прототип функции, который ожидается в качестве функции потока. Любое отклонение от него — это грубейшая ошибка, которая может повлечь за собой все что угодно.


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

AS>Гм. Вообще то, тут сказано, что GetExitCodeThread не работает именно для CreateRemoteThread, для CreateThread это все вполне работоспособно. Вы можете не доверять MSDN — это Ваше право, но не дай Бог Вам потом "вживую" встретить пострадавшего от этого недоверия пользователя вашей программы


Ну, если ты такой адепт MSDN, то почему не критиковал Read/WriteProcessMemory
без остановки потоков чужого процесса, если прямо указано, что они
для отладки. Кажется, обсуждаемый способ был признан правильным?

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

LT>> ExitCode возвращаемым CreateThread, бо реализация его построена на CRT.

AS> Какой CRT? Если имеется ввиду C run time, то тут это не при чем, если что то еще — тогда я видимо не в курсе этого чего то еще


Скучно все время писать длинно CreateRemoteThread, пишу CRT — поверь не я это первый придумал.

--
С уважением, LVT.
--
С уважением, LVT
Получить ProcessID, имея hProcess?
От: LeonV  
Дата: 28.08.03 18:56
Оценка:
Как можно получить PID, если есть hProcess? Ситуация такова: стартует приложение через ShellExecuteEx. Что это за приложение — заранее неизвестно, так как в ShellExecuteEx я передаю путь к файлу, который требуется открыть.

Далее необходимо послать сообщение окну того приложения, которое запустилось для открытия этого файла. После запуска процесса я делаю EnumWindows, а в функции EnumWindowsProc получаю PID процесса, в котором каждое окошко создано — GetWindowThreadProcessId. Один из этих PID — тот, который запустила ShellExecuteEx. По идее, их надо бы сравнить, но у меня на выходе ShellExecuteEx есть hProcess, а не пид. Как быть? Единственный способ узнать пид запущенного процесса, как я понял — вызвать CreateProcess и пид будет возвращен в структуре PROCESS_INFORMATION.

Кто поможет?

--------------------
PS.
Мной были испробован такой способ: (не смеяться!)

Моя прога:
1. Перед запуском процесса через ШелЕкзек я регистрю переменную окружения, допустим RunnerInvoked=1.
2. Создаю именованные объекты — событие и FileMapping.
3. Рождаю процесс через ЩелЕкзек, регистрю хук WH_GETMESSAGE.
4. Ожидаю поднятия события.


Теперь перенесемся в другой процесс :
5. Хук обрабатывается в DLL в которой сидит функция-обработчик хука WH_GETMESSAGE. Кроме того, при загрузке в процесс эта DLL проверяет переменную окружения RunnerInvoked и таким образом определяет, тот ли это процесс, который родился из под ShellExec. Ибо в остальные процессы эта длл тоже будет загружена. Переменная окружения от родителя наследуется только в тот процесс, который мне нужен .

6. Далее, если есть такая переменная, открываю именованный FileMapping и вписываю туда GetCurrentProcessId. Подымаю евент. Все.

А тут просыпается первоначальная прога, так как евент был поднят при загрузке длл в процесс, рожденный из под шел екзек:
7. Вычитываем из FileMapping значение пида.

Теперь я имею пид запущенного процесса, через такую вот задницу .
Верю, что есть способы получше (передавать PID через реестр с использованием выше описанной технологии не предлагать).
Re: Получить ProcessID, имея hProcess?
От: Блудов Павел Россия  
Дата: 29.08.03 01:57
Оценка:
Здравствуйте, LeonV, Вы писали:

LV>Как можно получить PID, если есть hProcess?


Для XP/.NET Server есть API ::GetProcessId(HANDLE hProcess);

Для NT более ранних версий подойдет

::NtQueryInformationProcess(HANDLE hProcess, ProcessBasicInformation,,,,)

см <winternl.h> из PSDK

Для Win31/9x/Me скорее всего, никак.
Re: Получить ProcessID, имея hProcess?
От: Sergey Ten http://www.fastalgo.com
Дата: 29.08.03 02:28
Оценка:
Здравствуйте, LeonV, Вы писали:

LV>Как можно получить PID, если есть hProcess? Ситуация такова: стартует приложение через ShellExecuteEx. Что это за приложение — заранее неизвестно, так как в ShellExecuteEx я передаю путь к файлу, который требуется открыть.


Предлагаю свой изощренный способ (навеяно статьей в RSDN о перехвате API):


type
  TInjectCode = packed record
    instr_call_getpid   : WORD;   // call []
    adr_from_call_getpid: DWORD;  // @GetCurrentProcessID

    instr_mov_ax: BYTE;           // mov,
    instr_mov_opcode: BYTE;       //  ax,
    adr_to_move : DWORD;          //   [target]

    instr_push_exitthread_arg: BYTE;  // push
    exitthread_arg           : DWORD; // 0

    instr_call_exitthread   : WORD;   // call
    adr_from_call_exitthread: DWORD;  // @ExitThread

    addr_getpid    : DWORD;           // Address of GetCurrentProcessID
    addr_exitthread: DWORD;           // Address of ExitThread

    addr_ret_val: DWORD; // Here the pid will be written
  end;

function GetPIDByHandle(AProcessHandle: THandle): DWORD;
var
  LInjectCode: TInjectCode;
  LThread: THandle;
  LThreadID: Cardinal;
  P: Pointer;
  N: Cardinal;
begin
  // Allocate memory for further writing and execution of machine instructions
  P := VirtualAllocEx(AProcessHandle, nil, SizeOf(LInjectCode),
    MEM_COMMIT, PAGE_EXECUTE_READWRITE);

  // Fill the region with machine instructions
  //   call GetCurrentProcessID
  //   mov [adr_to_move], eax
  //   push 0
  //   call ExitThread
  with LInjectCode do
  begin
    // Call GetCurrentProcessID in the context of target process
    instr_call_getpid    := $15ff; // call
    adr_from_call_getpid := DWORD(P) + DWORD(@LInjectCode.addr_getpid) - DWORD(@LInjectCode); // GetCurrentProcessID

    // Store the result for future fetching
    instr_mov_ax := $89; // mov [target_address], eax
    instr_mov_opcode := $05; // 
    adr_to_move  := DWORD(P) + DWORD(@LInjectCode.addr_ret_val) - DWORD(@LInjectCode);         // [target]

    // Call ExitThread
    instr_push_exitthread_arg := $68;
    exitthread_arg            := 0;

    instr_call_exitthread    := $15ff;
    adr_from_call_exitthread := DWORD(P) + DWORD(@LInjectCode.addr_exitthread) - DWORD(@LInjectCode);

    addr_getpid     := DWORD(GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetCurrentProcessId'));
    addr_exitthread := DWORD(GetProcAddress(GetModuleHandle('kernel32.dll'), 'ExitThread'));
  end;

  WriteProcessMemory(AProcessHandle, P, @LInjectCode, SizeOf(LInjectCode), N);

  // Create remote thread in the target process
  LThread := CreateRemoteThread(AProcessHandle, nil, 0, P,
    nil, 0, LThreadID);

  WaitForSingleObject(LThread, INFINITE);

  // Read back PID and free memory
  ReadProcessMemory(AProcessHandle, P, @LInjectCode, SizeOf(LInjectCode), N);
  VirtualFreeEx(AProcessHandle, P, SizeOf(LInjectCode), MEM_RELEASE);

  Result := LInjectCode.addr_ret_val;
end;
Re[2]: Получить ProcessID, имея hProcess?
От: Блудов Павел Россия  
Дата: 29.08.03 05:12
Оценка:
Здравствуйте, Sergey Ten, Вы писали:

ST>Предлагаю свой изощренный способ (навеяно статьей в RSDN о перехвате API):


Точно! В Win9x можно сделать xCreateRemoteThread(GetCurrentProcessId()).
Павел.
Re[4]: Получить ProcessID, имея hProcess?
От: Блудов Павел Россия  
Дата: 02.09.03 02:12
Оценка:
Здравствуйте, EM, Вы писали:

БП>>Точно! В Win9x можно сделать xCreateRemoteThread(GetCurrentProcessId()).


EM>Как раз в Win9x — то и нельзя — CreateRemoteThread() есть только в NT/2000/XP


xCreateRemoteThread() это функция из библиотеки elirt (см google).
Работает замечательно и в 9.x и в NT3.1

Павел.
Re[5]: Получить ProcessID, имея hProcess?
От: Блудов Павел Россия  
Дата: 02.09.03 02:48
Оценка:
Здравствуйте, Sergey Ten & Andrew S Вы писали:

AS>Думается, это слишком сложно.

ST>Имелось в виду вот это:
ST>http://help.madshi.net/CreateRemoteThread.htm

Скажу более. В этой библиотеке есть функция

DWORD ProcessHandleToId(HANDLE hProcess)

Которая делает все это. При желании ее можно от-туда выдрать.

Павел.
Re[4]: Получить ProcessID, имея hProcess?
От: Andrew S Россия http://alchemy-lab.com
Дата: 02.09.03 06:49
Оценка:
А вот и дополнение к пункту (2)

     DWORD TId = GetCurrentThreadId();  // Get ID of current thread
    DWORD Unobsfucator = 0;
    __asm
    {
        mov     eax, fs:[0x18]  //  pTIB = FS:[18h]  pointer to the thread information block
        sub     eax, 0x10         // pointer for the Thread Database 10h bytes upper
        xor     eax,[TId]        // This is unobsfucator variable
        mov     [Unobsfucator], eax
    }


Соответственнно, получить текущий PDB процесса можно: GetCurrentProcessId() ^ Unobsfucator.
Это для 95-х. Впрочем, должно работать и для других 9х систем. Возможно, с небольшими изменениями.

AS>Думается, это слишком сложно. В 9х, как утверждает MATT PIETREK, все гораздо проще. Первое, что надо помнить — процесс ID в 9х — это всего лишь некоторое обратимое преобразование указателя на PDB процесса (xor with "Obsfucator" DWORD). Т.к. PDB находятся в shared memory, то pid гарантированно уникальны. Второе — то, что PDB текущего процесса можно получить некоторым образом (см. пример к главе 3 — у меня в электронной книге, к сожалению, эта часть отсутствует). Получая PDB, мы можем определить таблицу хендлов, по таблице хандлов можем получить указатель на PDB нужного нам процесса, а из него, используя пресловутое преобразование (1) получить искомый PID процесса.

AS>Вот, примерно так.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Получить ProcessID, имея hProcess?
От: Leonid Troyanovsky  
Дата: 02.09.03 09:58
Оценка:
Здравствуйте, Sergey Ten, Вы писали:

ST>Здравствуйте, LeonV, Вы писали:


LV>>Как можно получить PID, если есть hProcess? Ситуация такова: стартует приложение через ShellExecuteEx. Что это за приложение — заранее неизвестно, так как в ShellExecuteEx я передаю путь к файлу, который требуется открыть.


ST>Предлагаю свой изощренный способ (навеяно статьей в RSDN о перехвате API):


В данном случае оно еще проще

http://groups.google.com/groups?selm=3BFF8FE3.55120942%40eco-pro.ru

--
С уважением, LVT.
--
С уважением, LVT
Re[3]: Получить ProcessID, имея hProcess?
От: Andrew S Россия http://alchemy-lab.com
Дата: 02.09.03 10:34
Оценка:
Гм. Насколько я понимаю, имеется ввиду это:

var
  hProcess, hThread: THandle;
  pGetCurrentProcessID: Pointer;
  rtid, pid: DWord;
..  
  pGetCurrentProcessID := GetProcAddress( GetModuleHandle('kernel32.dll'), 
       'GetCurrentProcessId');
  Win32Check(pGetCurrentProcessID <> nil);
  hThread:= CreateRemoteThread ( hProcess, 
                                 nil,
                                 0,
                                 pGetCurrentProcessID,
                                 nil,
                                 0,
                                 rtid);
  Win32Check(hThread <> 0);
  WaitForSingleObject(hThread, INFINITE);
  GetExitCodeThread(hThread, pid);
  CloseHandle(hThread);

  Caption := IntToStr(pid); // result


Итак, посмотрим определение функций

//  то, что должно выступать в качестве функции треда:
DWORD WINAPI ThreadProc(
  LPVOID lpParameter   // thread data
);

//  То, что мы ему передаем.
DWORD WINAPI GetCurrentProcessId(VOID);


Соглашение о передаче параметров winapi предусматривает то, что вызываемая функция очищает стек параметров. Таким образом, мы получаем на выходе из функции неправильный стек. Что будет дальше? Неизвестно. Скорее всего, никто ничего не заметит. На данной системе с данным процессом. Но если случится (а это обязательно случится) большой бах — то он случится даже не в вашем, а чужом процессе.

И в любом случае — этот метод не решает проблемы с 9х системами.В общем, лучше, правильнее и быстрее использовать в случае winnt (Nt/Zw)QueryInformationProcess.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Получить ProcessID, имея hProcess?
От: Аноним  
Дата: 03.09.03 04:19
Оценка:
Здравствуйте, Sergey Ten, Вы писали:

ST>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, LeonV, Вы писали:


LV>>>Как можно получить PID, если есть hProcess?


А>>Чего то я не понял. Почему OpenProcess не заюзать?

А>>Передаешь туда PID и сравниваешь хэндлы.

ST>OpenProcess вернет другой хэндл каждый раз про открытии того же самого процесса:



А если так:
#include <windows.h>

main()
{
int i;

    HANDLE h;
    for (i = 0; i < 10; i++)
    {
    h = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId());
        CloseHandle(h);
    }
}


Re[5]: Получить ProcessID, имея hProcess?
От: Аноним  
Дата: 03.09.03 04:48
Оценка:
Здравствуйте, vasketsov, Вы писали:

V>Здравствуйте, Аноним, Вы писали:


А>>>>Чего то я не понял. Почему OpenProcess не заюзать?

А>>>>Передаешь туда PID и сравниваешь хэндлы.
А>>А если так:
V>А хоть как.
V>OpenProcess создает НОВЫЙ хэндл.
V>А хэндлы по своей природе не сравниваются друг с другом.
V>Аналогия — утверждение навернства 2-х дверей, если у этих дверей одинаковые ручки.
V>К тому же, если первый хэндл был валиден в Вашем ВАП, то OpenProcess НИКОГДА не вернет аналогичную величину, потка тот хэндл не будет закрыт, так как нумерация хэндлов для одного процесса сквозная независимо от их типа (процесс, поток, файл, событие и т.д.).

Ну чтож. Пожалуй возразить мне нечем
Re[6]: Получить ProcessID, имея hProcess?
От: Leonid Troyanovsky  
Дата: 03.09.03 05:27
Оценка:
Здравствуйте, Andrew S, Вы писали:


AS>1. Я не описывал никаких приемов формирования стека функции. Вы меня с кем-то путаете


Я никого ни с кем не путал, IMHO.
Исторически первой была техника Джефа, а Прасад, как раз, предложил вариант, описанный тобой. Именно поэтому они в таком порядке и были упомянуты.
Во всяком случае, я считал, что это нужно знать каждому, кто заинтересовался этим вопросом.


LT>> А чем оно отличается от вызыва твоей ThreadFunc, которой также передается параметр — адрес структуры InjectInfo?


AS>При вызове функций главным является соглашение о вызове (в данном случае обе winapi) и количество параметров, которые они в себя принимают. ThreadProc принимает 1 параметр (eq 4 байта на стеке), GetCurrentProcessId принимает 0 параметров. Итак, что происходит. Caller делает перед вызовом ThreadProc push lpParameter, ожидая, что по возвращению, ThreadProc вернет результат в eax и очистит стек (например, ret 2). Однако, GetCurrentProcessId этого не делает (просто ret), хотя и возвращает результат в eax. Итого — внешне все ОК, хотя на самом деле далеко не так — портится caller's стек.


Какой-какой caller? Речь идет о стеке того самого потока.
Если бы было так, как ты описываешь, то удаленному потоку никогда и не удалось
воспользоваться полученным параметром. По-крайней мере, поток вызывал бы
AV по выходу из функции.

AS>И теперь — самое главное. MSDN:

AS>

AS>process can obtain the return value of the ThreadProc of a thread it created with CreateThread by calling the GetExitCodeThread function. A process cannot obtain the return value from the ThreadProc of a thread it created with CreateRemoteThread.


Это надо воспринимать несколько критически, иначе бы мы и не могли пользоваться
ExitCode возвращаемым CreateThread, бо реализация его построена на CRT.

--
С уважением, LVT.
--
С уважением, LVT
Re[7]: Получить ProcessID, имея hProcess?
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.09.03 06:05
Оценка:
Caller — это то, что вызывает функцию потока. Она же не сама по себе вызывается, верно?
Тем более, что по выходу из потока код возврата сохраняется в TDB.

LT> Какой-какой caller? Речь идет о стеке того самого потока.

LT> Если бы было так, как ты описываешь, то удаленному потоку никогда и не удалось
LT> воспользоваться полученным параметром. По-крайней мере, поток вызывал бы
LT> AV по выходу из функции.

А кто сказал, что он этого не делает? Вы можете достоверно это определить на всех системах линейки NT + то, что это происходит в другом процессе? Еще раз. Вам указан прототип функции, который ожидается в качестве функции потока. Любое отклонение от него — это грубейшая ошибка, которая может повлечь за собой все что угодно.

AS>>И теперь — самое главное. MSDN:

AS>>

AS>>process can obtain the return value of the ThreadProc of a thread it created with CreateThread by calling the GetExitCodeThread function. A process cannot obtain the return value from the ThreadProc of a thread it created with CreateRemoteThread.


Гм. Вообще то, тут сказано, что GetExitCodeThread не работает именно для CreateRemoteThread, для CreateThread это все вполне работоспособно. Вы можете не доверять MSDN — это Ваше право, но не дай Бог Вам потом "вживую" встретить пострадавшего от этого недоверия пользователя вашей программы
LT> Это надо воспринимать несколько критически, иначе бы мы и не могли пользоваться
LT> ExitCode возвращаемым CreateThread, бо реализация его построена на CRT.

Какой CRT? Если имеется ввиду C run time, то тут это не при чем, если что то еще — тогда я видимо не в курсе этого чего то еще
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Получить ProcessID, имея hProcess?
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.09.03 08:14
Оценка:
Честно говоря, я устал говорить то же самое на протяжении 4-х постингов. Вы можете писАть для себя как угодно, я думаю, эта тема для меня (и не только) исчерпана.
Спасибо за внимание.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[10]: Получить ProcessID, имея hProcess?
От: Leonid Troyanovsky  
Дата: 03.09.03 11:45
Оценка:
Приветствую, Andrew.

> Честно говоря, я устал говорить то же самое на протяжении 4-х постингов. Вы можете писАть для себя как угодно, я думаю, эта тема для меня (и не только) исчерпана.


Экий бука. А я хотел порадовать откровением самого Прасада.
Оно могло бы, IMHO, тебя утешить.

От:Prasad Dabak (pdabak@yahoo.com)
Заголовок:Re: getting command line of a process
Группы новостей:microsoft.public.win32.programmer.kernel
Число:2001-07-17 23:59:25 PST


Hello,

You are *absolutely* right about your suspicion.

The actual thread function is called from BaseThreadStart function in
KERNEL32.DLL and once your function returns, the BaseThreadStart
function calls ExitThread. Hence, I believe, it does not matter if
there is any extra parameter present on stack.

Hence it works.

The *safest* way would be to inject some function (containing no
relocatable instructions) in the target process, inject some data
structure containing all the required data and then create a remote
thread and pass it pointer to the data structure. After the thread
returns read back the data strcuture from the target process to get
the result.

e.g.

You can inject a data structure and a function like below.

typedef struct GetCmdLnData_t {
FARPROC pfnGetCommandLineA;
char CmdLn[2000];
} GETCMDLNDATA, *PGETCMDLNDATA;

RGetCommandLineA(PGETCMDLNDATA pGetCmdlnData)
{
char *p;
int i;

pGetCmdlnData->CmdLn[i]='\0'
p=(char *)pGetCmdlnData->pfnGetCommandLineA();
if (p) {
for (i=0; p[i]; i++) {
pGetCmdlnData->CmdLn[i]=p[i];
} pGetCmdlnData->CmdLn[i]='\0';
} return 0;
}

-Prasad


Daniel Lohmann <daniel@uni-koblenz.de> wrote in message news:&lt;bqg9lto0h6gio4kbtreo6n0un6jgpk7mdh@4ax.com&gt;...
> On 17 Jul 2001 04:29:40 -0700, pdabak@yahoo.com (Prasad Dabak) wrote:
>
> >Hello,
> >
> >Here is the sample program to do it. It accepts process id on the
> >command line and prints commandline for that process. You will have to
> >enable debug privilege to access commandline for processes not running
> >in your own security context.
>
> Nice example, Prasad
>
> But I have a question there. I thought about doing it exactly the same
> way you suggested (calling GetCommandLineA/W() as thread function via
> CreateRemoteThread), but decided it would not work: An ordinary thread
> function accepts a single 32 bit parameter on the stack and because it
> is called as _stdcall it *must* remove the parameter from the stack.
> GetCommandLine() expects nothing to be passed on the stack and
> therefore does not remove anything.
>
> Does this work only because the thread terminates after calling
> GetCommandLine() and nobody worries about the not-cleaned-up stack or
> I'm missing something?
>
>
> Daniel
--

> Спасибо за внимание.


Ну, извини, если чего.

--
С уважением, LVT.
Posted via RSDN NNTP Server 1.7 beta
--
С уважением, LVT
Re[11]: Получить ProcessID, имея hProcess?
От: Блудов Павел Россия  
Дата: 04.09.03 03:28
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:

>> Честно говоря, я устал говорить то же самое на протяжении 4-х постингов. Вы можете писАть для себя как угодно, я думаю, эта тема для меня (и не только) исчерпана.


LT> Экий бука.


Тема исчерпана, так как и для 9x и для NT есть более простые решения, чем CRT(GetCurrentProcessId()).
И совершенно не важно, будет ли этот способ работать или нет. Он никому не нужен.

Павел.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.