релоки должны указывать на выделенную память ? --- Сообщение объединено, 28 янв 2024 --- и системой... --- Сообщение объединено, 28 янв 2024 --- rmn, CreateThread в DllMain ?
Да: в бинарнике все обращения к данным предполагают, что бинарник загружен по фиксированному адресу (ImageBase). Если бинарник надо загрузить по другому адресу, все такие места надо пропатчить. Список всех этих мест лежит в таблице релоков. Ты идёшь по каждому смещению из таблицы релоков, и, в зависимости от размера указателя в байтах, пересчитываешь новый адрес: NewAddress = OldAddress - OldImageBase + NewImageBase
HoShiMin ,поблема в том что релоки это RVA адреса,а если длл разместить по произвольному адресу,то есть прочитать с диска в произвольную область памяти,здесь их придётся как-то пересчитывать,особенно когда образ загружен не по ImageBase
Да, создать поток в DllMain() безопасно. Главное, помнить, что хотя CreateThread() выполнится успешно и вернет валидный хендл, твоя функция потока не начнет выполняться, пока твоя DllMain() не завершится, поэтому ждать от потока что-то сразу после вызова CreateThread() - это гарантированный дедлок. Но лучше, конечно, класс-хелпер для создания потока заюзать, требующий для сборки C++24 и собирающийся кастомным тулчейном на джва гига всего за 7 секунд на i9-over9000
rmn, не подскажете, в чем ошибка? Создаю 2 Pipe с помощью CreatePipe. Создаю 1 CreateProcess. Код (Text): procedure StartExe(s: string); var WaitThreadId: Cardinal; StartupInfo: TStartupInfo; SecurityAttributes: TSecurityAttributes; ProcessInformation: TProcessInformation; begin Form1.Memo2.Lines.Add('Process started.'); ZeroMemory(@SecurityAttributes, SizeOf(SecurityAttributes)); SecurityAttributes.nLength := SizeOf(TSecurityAttributes); SecurityAttributes.lpSecurityDescriptor := nil; SecurityAttributes.bInheritHandle := True; CreatePipe(hPipeInputRead, hPipeInputWrite, @SecurityAttributes, 0); CreatePipe(hPipeOutputRead, hPipeOutputWrite, @SecurityAttributes, 0); ZeroMemory(@StartupInfo, SizeOf(TStartupInfo)); ZeroMemory(@ProcessInformation, SizeOf(TProcessInformation)); GetStartupInfo(StartupInfo); StartupInfo.cb := SizeOf(TStartupInfo); StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; StartupInfo.wShowWindow := SW_HIDE; StartupInfo.hStdInput := hPipeInputRead; StartupInfo.hStdOutput := hPipeOutputWrite; StartupInfo.hStdError := hPipeOutputWrite; if CreateProcess(nil, PChar(s), nil, nil, True, CREATE_NO_WINDOW{CREATE_NEW_CONSOLE}, nil, nil, StartupInfo, ProcessInformation) then begin hProcess := ProcessInformation.hProcess; hThread := CreateThread(nil, 0, @ReadThreadProc, nil, 0, ThreadId); CreateThread(nil, 0, @WaitThread, nil, 0, WaitThreadId); //WaitForSingleObject(hProcess, INFINITE); end; end; После CreateProcess создаю поток для чтения из Pipe: Код (Text): procedure ReadThreadProc; var buf: array [0..4096] of Char; BytesCount, lpTotalBytesAvail: Cardinal; begin Terminated := false; while not Terminated do begin if WaitForSingleObject(hProcess, 10) = WAIT_TIMEOUT then begin if PeekNamedPipe(hPipeOutputRead, nil, 0, nil, @lpTotalBytesAvail, nil) then begin if lpTotalBytesAvail > 0 then begin ZeroMemory(@buf, SizeOf(buf)); if ReadFile(hPipeOutputRead, buf, Length(buf), BytesCount, nil) then begin if BytesCount <> 0 then begin OemToAnsiBuff(buf, buf, BytesCount); Form1.Memo2.Text := Form1.Memo2.Text + Copy(buf, 1, BytesCount); end; end; end; end; end; end; end; При записи в Pipe время от времени возникает Access Violation, External exception C0000008: Код (Text): procedure InputText(s: string); var i: integer; BytesCount: Cardinal; buf: array [0..4096] of Char; begin if Length(s) < 4090 then begin ZeroMemory(@buf, SizeOf(buf)); lstrcpy(buf, PChar(s)); lstrcat(buf, #13#10); for i := 0 to Length(buf) - 1 do begin WriteFile(hPipeInputWrite, buf[i], 1, BytesCount, nil); end; //WriteFile(hPipeInputWrite, buf, Length(buf), BytesCount, nil); end; end; Код для того, чтобы: запустить процесс, получить вывод. Потом сделать ввод, затем считать вывод, и так постоянно. Не могу понять из за чего может возникать исключение
Есть хорошие статьи в http://rsdn.org/ как подготовить и грузить DLL в про-во процесса http://rsdn.org/article/baseserv/peloader.xml?print Загрузчик PE-файлов Исследование формата Portable Executable, сопровождающееся написанием PE-загрузчика http://rsdn.org/article/baseserv/InjectDll.xml?print Способ принудительной загрузки DLL в адресное пространство процесса --- Сообщение объединено, 28 янв 2024 --- И еще полезная статья........ http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1294 TUnRar без DLL