![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Вызываю функцию CreateProcess с ключами DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS, получаю хэндл процесса, спокойно его (в смысле память процесса) читаю/пишу, запрашиваю состояния памяти, какбе все норм, но вот вызывая GetModuleFileNameEx(или GetModuleBaseName) получаю в LastError = 6 (INVALID_HANDLE_VALUE).
Тут есть какая-то специфика использования этой ф-ии, или может я что-то не то понаделал? Задача - получить имя и путь запущенного приложения. P.S. При приаттачивании процесса функции работают корректно. Уж не придется ли переходить на NtQuerySystemInformation? Последний раз редактировалось 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, а не что-то другое.
|
|
#4
|
||||
|
||||
|
Вот оно чё:
Цитата:
ПРидется ковырять в сторону NtQuerySystemInformation, или еще того хуже. Последний раз редактировалось 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 |