|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Ошибка получения имени модуля
Вызываю функцию CreateProcess с ключами DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS, получаю хэндл процесса, спокойно его (в смысле память процесса) читаю/пишу, запрашиваю состояния памяти, какбе все норм, но вот вызывая GetModuleFileNameEx(или GetModuleBaseName) получаю в LastError = 6 (INVALID_HANDLE_VALUE).
Тут есть какая-то специфика использования этой ф-ии, или может я что-то не то понаделал? Задача - получить имя и путь запущенного приложения. P.S. При приаттачивании процесса функции работают корректно. Уж не придется ли переходить на NtQuerySystemInformation? — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 04.07.2012 в 15:40. |
#2
|
|||
|
|||
такая вроде работает
Код:
uses psapi; function ProcessFileName(PID: DWORD): string; var Handle: THandle; begin Result := ''; Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID); if Handle <> 0 then try SetLength(Result, MAX_PATH); if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then SetLength(Result, StrLen(PChar(Result))) else Result := ''; finally CloseHandle(Handle); end; end; |
#3
|
||||
|
||||
Так-то она работает, а вот при пошаговой загрузке процесса почему-то не хочет (хотя тот же процес эксплорер отображает информацию). Т.е. я отлавливаю событие ON_DLL_LOAD и пытаюсь получить имя модуля по base address, в итоге фига с маслом. Но все равно не понятно, почему результат invalid handle, а не что-то другое.
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#4
|
||||
|
||||
Вот оно чё:
Цитата:
ПРидется ковырять в сторону NtQuerySystemInformation, или еще того хуже. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 04.07.2012 в 18:39. |
#5
|
||||
|
||||
Вот решение:
Код:
type PDebugModule = ^TDebugModule; TDebugModule = packed record Reserved: array [0..1] of Cardinal; Base: Cardinal; Size: Cardinal; Flags: Cardinal; Index: Word; Unknown: Word; LoadCount: Word; ModuleNameOffset: Word; ImageName: array [0..$FF] of Char; end; type PDebugModuleInformation = ^TDebugModuleInformation; TDebugModuleInformation = record Count: Cardinal; Modules: array [0..0] of TDebugModule; end; PDebugBuffer = ^TDebugBuffer; TDebugBuffer = record SectionHandle: THandle; SectionBase: Pointer; RemoteSectionBase: Pointer; SectionBaseDelta: Cardinal; EventPairHandle: THandle; Unknown: array [0..1] of Cardinal; RemoteThreadHandle: THandle; InfoClassMask: Cardinal; SizeOfInfo: Cardinal; AllocatedSize: Cardinal; SectionSize: Cardinal; ModuleInformation: PDebugModuleInformation; BackTraceInformation: Pointer; HeapInformation: Pointer; LockInformation: Pointer; Reserved: array [0..7] of Pointer; end; const PDI_MODULES = $01; ntdll = 'ntdll.dll'; var Form1: TForm1; HNtDll: HMODULE; type TFNRtlCreateQueryDebugBuffer = function(Size: Cardinal; EventPair: Boolean): PDebugBuffer; stdcall; TFNRtlQueryProcessDebugInformation = function(ProcessId, DebugInfoClassMask: Cardinal; var DebugBuffer: TDebugBuffer): Integer; stdcall; TFNRtlDestroyQueryDebugBuffer = function(DebugBuffer: PDebugBuffer): Integer; stdcall; var RtlCreateQueryDebugBuffer: TFNRtlCreateQueryDebugBuffer; RtlQueryProcessDebugInformation: TFNRtlQueryProcessDebugInformation; RtlDestroyQueryDebugBuffer: TFNRtlDestroyQueryDebugBuffer; implementation {$R *.dfm} function LoadRtlQueryDebug: LongBool; begin if HNtDll = 0 then begin HNtDll := LoadLibrary(ntdll); if HNtDll <> 0 then begin RtlCreateQueryDebugBuffer := GetProcAddress(HNtDll, 'RtlCreateQueryDebugBuffer'); RtlQueryProcessDebugInformation := GetProcAddress(HNtDll, 'RtlQueryProcessDebugInformation'); RtlDestroyQueryDebugBuffer := GetProcAddress(HNtDll, 'RtlDestroyQueryDebugBuffer'); end; end; Result := Assigned(RtlCreateQueryDebugBuffer) and Assigned(RtlQueryProcessDebugInformation) and Assigned(RtlQueryProcessDebugInformation); end; function getProcessModule(pid : cardinal):String; var DbgBuffer: PDebugBuffer; Loop: Integer; s:string; begin Result:=''; if not LoadRtlQueryDebug then Exit; DbgBuffer := RtlCreateQueryDebugBuffer(0, false); if Assigned(DbgBuffer) then try if RtlQueryProcessDebugInformation(pid, PDI_MODULES, DbgBuffer^) >= 0 then begin for Loop := 0 to DbgBuffer.ModuleInformation.Count - 1 do S:=S+#13#10+DbgBuffer.ModuleInformation.Modules[Loop].ImageName; Result:=S; end; finally RtlDestroyQueryDebugBuffer(DbgBuffer); end; end; procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Text:=getProcessModule(GetCurrentProcessId); end; Интересно работает, заставляет процесс подгрузить все модули без сигнализирования события отладчику. Решение сперто отсюда: http://forum.sources.ru/index.php?showtopic=324532 — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |