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


Как раз в Win9x — то и нельзя — CreateRemoteThread() есть только в NT/2000/XP
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
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[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?
От: Блудов Павел Россия  
Дата: 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[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[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?
От: Аноним  
Дата: 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[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[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
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.