![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Непонятности с GetWindowModuleFileName
Чапаев © (2005-11-14 11:56:00)По идее, функция должна записать в буфер имя и путь к исполняемому файлу, который создал окно.
Делаю EnumWindows(), в процедуре обратного вызова вызываю эту функцию. Если вызываю из хука на мышь, не возвращает ничего, если из обычной программы -- всегда возвращает имя этой самой программы. В чём глюк?
shadowonline (2005-12-26 16:24:00) [1]Странно, поставил Delphi 6, скомпилировал ошибка осталась. Только exe-к на 70Кб раздулся. Похоже руки у меня точно не стого места ростут(Но как этот же exe-к работает под Win 2000????).
shadowonline (2005-12-26 16:23:00) [2]Странно, поставил Delphi 6, скомпилировал ошибка осталась. Только exe-к на 70Кб раздулся. Похоже руки у меня точно не стого места ростут(Но как этот же exe-к работает под Win 2000????).
shadowonline (2005-12-26 13:30:00) [3]Может есть какой патчь для Delphi 5
Игорь Шевченко (2005-12-26 12:35:00) [4]Код в [6] проверялся именно на XP SP2
shadowonline (2005-12-26 12:11:00) [5]Предустановлен SP2. Может быть проблемма в винде?
Игорь Шевченко (2005-12-26 11:18:00) [6]Какой сервис-пак для XP установлен ?
shadowonline (2005-12-24 10:44:00) [7]Дополнительные тесты показали. Происходит ошибка в строке
if NOT ReadProcessMemory(AProcessHandle,
@PPEB(PEBAddress)^.ProcessParameters,
@ATargetProcessParametersPointer, SizeOf(Ptr32),
AReturned) then
RaiseLastWin32Error();
Ошибка 299 Запрос ReadProcessMemory был выполнен только частично.
Это под ХР, а под 2000 работает.(по поводу 87 ошибки похоже я криво окно искал, извиняюсь)
shadowonline (2005-12-24 10:18:00) [8]Теперь понятно в чем фишка. Но что то руки у меня кривые.
Нашел и состряпал(перевод из С) следующий код, все равно не помогает.
Может какую ни будь другую привилегию нужно или что не так делаю.
Функция возвращает успех но ошибка "87. Параметр задан неверно." все равно вылетает.
If EnableDebugPrivilege('SEDEBUGPRIVILEGE') Then ShowMessage('Yes!!!')
Else ShowMessage('No!!!');
function EnableDebugPrivilege(seName:String):Boolean;
Var
hToken, prevst: Cardinal;
tp, tk: TOKEN_PRIVILEGES;
Begin
Result:= True;
If (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)) Then Begin
tp.PrivilegeCount:= 1;
If LookupPrivilegeValue(nil, PChar(seName), tp.Privileges[0].Luid) Then Begin
tp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
If not AdjustTokenPrivileges(hToken, False, tp, sizeof(tp), tk, prevst) Then Result:= False;
End
Else Result:= False;
CloseHandle(hToken);
End
Else Result:= False;
End;
Игорь Шевченко (2005-12-23 15:57:00) [9]
> if AProcessHandle = 0 then
Не смог открыть процесс.
С привилегиями все хорошо ?
shadowonline (2005-12-23 15:36:00) [10]?????????. Если отлажевать под Win 2000 то ошибок вообще нет(все работает). Как же тогда ее можно отладить? Или только у меня под XP не работает????
shadowonline (2005-12-23 15:30:00) [11]В первом
if AProcessHandle = 0 then
RaiseLastWin32Error();//Здесь
PEBAddress := RtlGetPeb;
Игорь Шевченко (2005-12-23 14:39:00) [12]shadowonline © (23.12.05 13:45) [11]
> Отладка показала что ошибка происходит после вызова RaiseLastWin32Error();
> .
RaiseLastWin32Error в этом коде вызывается четыре раза. Мне за догадливость, в каком именно месте происходит ошибка, денег не платят.
shadowonline (2005-12-23 13:45:00) [13]Извиняюсь, ошибся!!! Отладка показала что ошибка происходит после вызова RaiseLastWin32Error();. Причем брекпоинт внутри RaiseLastWin32Error(); не отрабатывает(можно предположить что она и не вызывается). Нечего не понимаю. Может у меня руки кривые, но под Win 2000 работает однако.
Игорь Шевченко (2005-12-23 11:23:00) [14]shadowonline © (23.12.05 07:40) [9]
Бред. Пройди отладчиком.
shadowonline (2005-12-23 07:40:00) [15]Ругается на строку "PEBAddress:= RtlGetPeb;" вызов асемблера.
Говорит ошибка 87. Параметр задан неверно.
Игорь Шевченко (2005-12-22 17:47:00) [16]
> опять не работает.
Как именно не работает ?
shadowonline (2005-12-22 17:17:00) [17]Спасибо за код. Работает!
Вот только возникла проблема при переходе на Win XP, опять не работает.
Может там опять поменяли адрес блока PEB.
Помогите опять найти PEB блок в XP!!!
Игорь Шевченко (2005-11-18 21:40:00) [18]Чапаев © (18.11.05 18:14) [5]
Спасибо. В этих системах поменялся адрес блока PEB.
Вот такой код работает:
function RtlGetPeb: Cardinal; assembler;
asm
mov eax,fs:[24]
mov eax,[eax+48]
end;
{ Получение командной строки для процесса выбранного окна }
function HSGetWindowCommandLine (AWindowHandle : HWND) : String;
var
PEBAddress: Cardinal{ = $7FFDF000};
var
AProcessID : DWORD;
AProcessHandle : THandle;
ATargetProcessParametersPointer : Ptr32;
ATargetProcessParameters : TRTL_USER_PROCESS_PARAMETERS;
ATargetCommandLine : array[0..MAX_PATH] of WideChar;
AReturned : DWORD;
APathBytes : WORD;
begin
Result := '';
{ Алгоритм пригоден только для NT-платформ }
if HSQuerySystemInfo(hsiNTPlatform) then begin
{ PID для процесса, создавшего окно }
{$IFDEF VER140}
GetWindowThreadProcessID(AWindowHandle, AProcessID);
{$ELSE}
GetWindowThreadProcessID(AWindowHandle, @AProcessID);
{$ENDIF}
{ handle этого процесса }
AProcessHandle := OpenProcess(PROCESS_VM_READ or PROCESS_VM_OPERATION,
false, AProcessID);
if AProcessHandle = 0 then
RaiseLastWin32Error();
PEBAddress := RtlGetPeb;
try
{ Получение адреса структуры параметров процесса }
if NOT ReadProcessMemory(AProcessHandle,
{ Этот оператор нужен для подсчета смещения в блоке
PEB на указатель на параметры процесса }
@PPEB(PEBAddress)^.ProcessParameters,
@ATargetProcessParametersPointer, SizeOf(Ptr32),
AReturned) then
RaiseLastWin32Error();
{ Проверка избыточна, но вставлена для пущей надежности. }
if AReturned <> SizeOf(Pointer) then
raise Exception.CreateFmt(
'ReadProcessMemory прочитала неверное количество данных, ожидалось %d, получено %d',
[SizeOf(Ptr32), AReturned]);
{ Получение структуры параметров процесса }
if NOT ReadProcessMemory(AProcessHandle, ATargetProcessParametersPointer,
@ATargetProcessParameters,
SizeOf(ATargetProcessParameters),
AReturned) then
RaiseLastWin32Error();
{ Проверка избыточна, но вставлена для пущей надежности. }
if AReturned <> SizeOf(ATargetProcessParameters) then
raise Exception.CreateFmt(
'ReadProcessMemory прочитала неверное количество данных, ожидалось %d, получено %d',
[SizeOf(ATargetProcessParameters), AReturned]);
{ размер командной строки в байтах }
APathBytes := ATargetProcessParameters.CommandLine.Length;
if APathBytes > MAX_PATH * SizeOf(WideChar) then
APathBytes := MAX_PATH * SizeOf(WideChar);
{ Получение командной строки для указанного процесса }
if not ReadProcessMemory(AProcessHandle,
ATargetProcessParameters.CommandLine.Buffer,
@ATargetCommandLine,
APathBytes,
AReturned) then
RaiseLastWin32Error();
{ Для преобразования в Ansi подсчитывается число символов Unicode без
завершающего нуля. lstrlenW почему-то дала неверный результат. Странно.}
Result := WideCharLenToString(ATargetCommandLine,
Pred(AReturned DIV SizeOf(WideChar)));
finally
CloseHandle(AProcessHandle);
end;
end;
end;
Чапаев (2005-11-18 18:14:00) [19]
> Привилегиев видать нету.
На домашнем компе? Под администраторским аккаунтом? Да должно бы хватить... ;-)
Игорь Шевченко (2005-11-17 12:27:00) [20]Чапаев © (17.11.05 11:28) [2]
Привилегиев видать нету.