Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.07.24;
Скачать: CL | DM;

Вниз

Хук   Найти похожие ветки 

 
Pavia ©   (2015-09-06 21:57) [0]

Как поставить хук на только что созданный процесс? Вернее, так. EXE патчить не хочу. Поэтому хочу запустить процесс поймать момент загрузки. Вот только проблема как поймать момент загрузки?
До загрузки Dll нельзя все смещения тогда полетят. А как понять последний? Хотя можно вначале загрузить посчитать. Потом сделать сброс.

И пока под вопрос. Есть ли варианты остановить процесс вовремя запуска кроме как установить флаг отладки?


 
Pavia ©   (2015-09-06 22:31) [1]

Вопрос снят. Перестроил всю логику.


 
DayGaykin ©   (2015-09-08 13:18) [2]

Мало ли кто в поиске найдет.

Роуз поругал за подход:

// Код запускает Jetty и посылает Ctrl+C когда нужно.

function StopMe(Data: PStopMeData): Bool; stdcall;
begin
 Data^.WaitForMultipleObjects(2, PWOHandleArray(Data), False, INFINITE);
 Data^.GenerateConsoleCtrlEvent(0, 0);
 Data^.Sleep(20000);
 Data^.TerminateProcess(Data^.GetCurrentProcess, 1);
 Result := True;
end;

procedure TJavaThread.StartJava(var PI: TProcessInformation);
var
 SA: TSecurityAttributes;
 JLog: THandle;
 JLogFile: String;
 WorkDir, Params, Cmd: String;
 StopData: TStopMeData;
 SI: TStartupInfo;
 RemotePageSize, Dummy: Cardinal;
 StopProcPointer, StopProcDataPointer: Pointer;
 StopThread: Cardinal;
 StopEvent: THandle;
begin
 if PI.hProcess <> 0 then
   StopJava(PI);
 PI.hThread := 0;

 with SA do
 begin
   nlength := SizeOf(TSecurityAttributes) ;
   binherithandle := true;
   lpsecuritydescriptor := nil;
 end;

 JLogFile := ProgramDataPath + FormatDateTime("yyyy-mm-dd hhnnsszzz", Now)+".j.log";
 FExecuteSection := "CreateFile " + JLogFile;
 JLog := CreateFile(
   PChar(JLogFile),
   GENERIC_READ or GENERIC_WRITE,
   FILE_SHARE_READ or FILE_SHARE_WRITE,
   @SA,
   OPEN_ALWAYS,
   FILE_ATTRIBUTE_NORMAL,
   0
 );
 Win32Check(JLog <> INVALID_HANDLE_VALUE);
 try
   SetFilePointer(JLog, 0, nil, FILE_END);
   WorkDir := ProgramPath + "jportie\";
   FExecuteSection := "GetConnectionString";
   Params := " -Djportie.cs=" + AnsiQuotedStr(GetConnectionString, """);
   Params := Params +  " -Djportie.db.updates="  + AnsiQuotedStr(ExcludeTrailingPathDelimiter(ProgramPath + "updates"), """);
   Params := Params +  " -Djportie.db.backupcommand="  + AnsiQuotedStr(ProgramPath + "backup.exe", """);
   FExecuteSection := "getBgDataJavaParams";
   Params := Params + getBgDataJavaParams;
   ZeroMemory(@SI, SizeOf(SI));
   ZeroMemory(@Pi, SizeOf(PI));
   SI.cb := SizeOf(SI);
   SI.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
   SI.wShowWindow := SW_HIDE;
   SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
   SI.hStdOutput := JLog;
   SI.hStdError := JLog;

   Cmd := AnsiQuotedStr(ProgramPath + "rt70\bin\java.exe", """)
       + Params
       + " -jar "+AnsiQuotedStr(WorkDir + "start.jar", """);

   FExecuteSection := "CreateProcess " + Cmd;
   Win32Check(CreateProcess(
     nil,
     PChar(
        Cmd
     ),
     nil, nil,
     True,
     CREATE_SUSPENDED,
     nil,
     PChar(WorkDir),
     SI, PI
   ));
 finally
   CloseHandle(JLog);
 end;
 try
   StopEvent := 0;
   try
     FExecuteSection := "DuplicateHandle1";
     Win32Check(DuplicateHandle(GetCurrentProcess, GetCurrentProcess, PI.hProcess, @StopData.ParentProcess, PROCESS_ALL_ACCESS, True, 0));
     FExecuteSection := "DuplicateHandle2";
     StopEvent := CreateEvent(@SA, False, False, nil);
     Win32Check(DuplicateHandle(GetCurrentProcess, StopEvent, PI.hProcess, @StopData.StopEvent, PROCESS_ALL_ACCESS, True, 0));
     FExecuteSection := "GetProcAddress";
     StopData.GenerateConsoleCtrlEvent := GetProcAddress(GetModuleHandle(kernel32), PChar("GenerateConsoleCtrlEvent"));
     StopData.WaitForMultipleObjects := GetProcAddress(GetModuleHandle(kernel32), PChar("WaitForMultipleObjects"));
     StopData.Sleep := GetProcAddress(GetModuleHandle(kernel32), PChar("Sleep"));
     StopData.GetCurrentProcess := GetProcAddress(GetModuleHandle(kernel32), PChar("GetCurrentProcess"));
     StopData.TerminateProcess := GetProcAddress(GetModuleHandle(kernel32), PChar("TerminateProcess"));

     RemotePageSize := 1024;
     FExecuteSection := "VirtualAllocEx";
     StopProcPointer := VirtualAllocEx(PI.hProcess, nil, RemotePageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
     Win32Check(StopProcPointer <> nil);
     FExecuteSection := "WriteProcessMemory 1";
     Win32Check(WriteProcessMemory(PI.hProcess, StopProcPointer, @StopMe, RemotePageSize, Dummy));
     StopProcDataPointer := Pointer(Cardinal(StopProcPointer) - SizeOf(StopData) + RemotePageSize);
     FExecuteSection := "WriteProcessMemory 2";
     Win32Check(WriteProcessMemory(PI.hProcess, StopProcDataPointer, @StopData, SizeOf(StopData), Dummy));

     FExecuteSection := "CreateRemoteThread";
     StopThread := CreateRemoteThread(PI.hProcess, nil, 0, StopProcPointer, StopProcDataPointer, 0, Dummy);
     Win32Check(StopThread <> 0);
     CloseHandle(StopThread);
     ResumeThread(PI.hThread);
   finally
     CloseHandle(PI.hThread);
     PI.hThread := StopEvent;
   end;
 except
   TerminateProcess(PI.hProcess, 2);
   CloseHandle(PI.hProcess);
   CloseHandle(PI.hThread);
   PI.hProcess := 0;
   PI.hThread := 0;
   raise;
 end;
end;


 
Rouse_ ©   (2015-09-08 17:32) [3]


> Роуз поругал за подход:

Когда? Чет не помню.


 
DayGaykin ©   (2015-09-08 17:50) [4]


> Когда? Чет не помню.

Ты еще две статьи написал про JOB-ы. Это из той оперы.


 
Rouse_ ©   (2015-09-08 18:01) [5]

Ааа, понял. Ну да, было дело.


 
DayGaykin ©   (2015-09-08 18:20) [6]

Проблема в том, что мне нужно корректно завершать работу (по Ctrl+C так и происходит). С Job-ами - процесс просто убьется.

Иного способа передать Ctrl+C как GenerateConsoleCtrlEvent я не нашел, а эта функция не работает для удаленных процессов.


 
Rouse_ ©   (2015-09-08 18:59) [7]


> а эта функция не работает для удаленных процессов.

Как это?


 
DayGaykin ©   (2015-09-08 19:02) [8]

Может, конечно, я не так понял:
https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms683155%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

CTRL_C_EVENT
0
Generates a CTRL+C signal. This signal cannot be generated for process groups. If dwProcessGroupId is nonzero, this function will succeed, but the CTRL+C signal will not be received by processes within the specified process group.

Функция вернет успешный результат, а действия не будет. Так?


 
Rouse_ ©   (2015-09-08 19:12) [9]

Это не удаленные процессы, а порожденные твоей консолью.


 
Rouse_ ©   (2015-09-08 19:15) [10]

Так, на всякий, если потребуется:


> GenerateConsoleCtrlEvent causes the control handler functions
> of processes in the target group to be called. All console
> processes have a default handler function that calls the
> ExitProcess function. A console process can use the SetConsoleCtrlHandler
> function to install or remove other handler functions.


 
DayGaykin ©   (2015-09-08 20:06) [11]


> Это не удаленные процессы, а порожденные твоей консолью.

Так я ж не консолью порождаю. Этот код выполняется из сервиса. Это меняет дело?


 
Юрий Зотов ©   (2015-09-08 21:21) [12]

Была у меня такая задача. Есть чужая консольная программа, надо было сделать к ней некую графическую оболочку, чтобы через эту оболочку управлять той самой чужой консольной программой. Причем под словом "управлять" подразумевалось:
- запуск;
- перехват вывода в sysout;
- ожидание изменений файловых логов и чтение этих логов;
- suspend;
- resume;
- посылка команд в консоль;
- завершение.

Решил так. При старте моя программа создает консоль (я делал ее невидимой, но это на обязательно) с наследуемыми хэндлами I/O (а вот это обязательно). Из своей программы запускаю чужую, как дочерний (это тоже обязательно) процесс, наследующий те самые хендлы I/O (и это тоже обязательно). При этом чужая программа стартует в моей консоли.

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


 
Юрий Зотов ©   (2015-09-08 21:28) [13]

Это я рассказал применительно к "Иного способа передать Ctrl+C как GenerateConsoleCtrlEvent я не нашел, а эта функция не работает для удаленных процессов". Если имелись в виду процессы на той же машине, то их надо запустить в своей консоли - тогда все работает.


 
DayGaykin ©   (2015-09-09 00:05) [14]


> Юрий Зотов ©   (08.09.15 21:28) [13]

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


 
DayGaykin ©   (2015-09-09 00:06) [15]

П.С. Интересно, а в StdInput можно Ctrl+C послать?


 
DayGaykin ©   (2015-09-09 19:21) [16]

Блин, как же просто ларчик то открывается!

 Win32Check(AttachConsole(5464));
 Win32Check(SetConsoleCtrlHandler(nil, true));
 Win32Check(GenerateConsoleCtrlEvent(0, 0));


 
Rouse_ ©   (2015-09-09 19:38) [17]


> DayGaykin ©   (09.09.15 19:21) [16]
> Блин, как же просто ларчик то открывается!

Читайте MSDN - всея магия становится резко понятной :)



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

Текущий архив: 2016.07.24;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.012 c
2-1416291081
lewka
2014-11-18 09:11
2016.07.24
Кодировка TWebbrowser


15-1441149908
Юрий Зотов
2015-09-02 02:25
2016.07.24
Наиважнейшая проблема...


2-1416664103
Drowsy
2014-11-22 16:48
2016.07.24
Почему не очищаются Columns in DBGrid?


15-1442698201
Юрий
2015-09-20 00:30
2016.07.24
С днем рождения ! 20 сентября 2015 воскресенье


15-1444082370
d2pak
2015-10-06 00:59
2016.07.24
Что с Delphi World