Работа с чужими процессами
Code: |
// Поиск значения типа DWORD в указанном процессе // Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. // program search;
{$APPTYPE CONSOLE}
uses Windows, SysUtils;
var ProcessID: DWord; ProcessHandle: THandle; Mbi: TMemoryBasicInformation; Addr: DWord; Value: DWord; I: Cardinal; Buf: PChar; BytesRead: DWord; begin if ParamCount < 2 then begin WriteLn('Usage: search.exe processid value'); Exit; end;
ProcessID := StrToInt(ParamStr(1)); WriteLn('Process id: ' + IntToStr(ProcessID));
Value := StrToInt(ParamStr(2)); WriteLn('Value to search: ' + IntToStr(Value));
// // Открываем процесс // ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or PROCESS_VM_OPERATION, false, ProcessID);
if ProcessHandle <> 0 then try Addr := 0;
// // Перечисляем все регионы виртуальной памяти процесса // while VirtualQueryEx(ProcessHandle, Pointer(Addr), Mbi, SizeOf(Mbi)) <> 0 do begin // Uncomment чтобы увидеть список регионов, найденых в адресном пространстве // WriteLn('region: ' + IntToHex(Integer(Mbi.BaseAddress), 8) + // ' size: ' + IntToStr(Mbi.RegionSize));
// // Если региону выделена память, и регион не является "сторожевым" (как вершина стека), // то читаем этот регион // if (Mbi.State = MEM_COMMIT) and not ((Mbi.Protect and PAGE_GUARD) = PAGE_GUARD) then begin // // Это демонстрационная программа, поэтому здесь выделяется буфер под весь регион. // Регион может быть достаточно большим, поэтому лучше читать его блоками для экономии // памяти. Но здесь для простоты алгоритма вся оптимизация похерена. // GetMem(Buf, Mbi.RegionSize); try // // Читаем весь регион в выделенный буфер // if ReadProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead) then begin // // Ищем значение типа DWORD в буфере // for I := 0 to BytesRead - SizeOf(Value) do begin if PDWord(@Buf[I])^ = Value then // Найдено, выводим WriteLn('Value ' + IntToStr(Value) + ' found at ' + IntToHex(Integer(Cardinal(Mbi.BaseAddress) + I), 8)); end; end else WriteLn('Failed to read process memory ' + IntToStr(GetLastError));
finally FreeMem(Buf); end; end;
// Вычисляем адрес следуюшего региона Addr := Addr + Mbi.RegionSize; end;
finally CloseHandle(ProcessHandle); end else WriteLn('Failed to open process'); end. |
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Code: |
// Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. // program search; {©Drkb v.3}
{$APPTYPE CONSOLE}
uses Windows, SysUtils;
var ProcessID: DWord; ProcessHandle: THandle; Mbi: TMemoryBasicInformation; Addr: DWord; Value: DWord; I: Cardinal; Buf: PChar; BytesRead: DWord; begin if ParamCount < 2 then begin WriteLn('Usage: search.exe processid value'); Exit; end;
ProcessID := StrToInt(ParamStr(1)); WriteLn('Process id: ' + IntToStr(ProcessID));
Value := StrToInt(ParamStr(2)); WriteLn('Value to search: ' + IntToStr(Value));
// // Открываем процесс // ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or PROCESS_VM_OPERATION, false, ProcessID);
if ProcessHandle <> 0 then try Addr := 0;
// // Перечисляем все регионы виртуальной памяти процесса // while VirtualQueryEx(ProcessHandle, Pointer(Addr), Mbi, SizeOf(Mbi)) <> 0 do begin // Uncomment чтобы увидеть список регионов, найденых в адресном пространстве // WriteLn('region: ' + IntToHex(Integer(Mbi.BaseAddress), 8) + // ' size: ' + IntToStr(Mbi.RegionSize));
// // Если региону выделена память, и регион не является "сторожевым" (как вершина стека), // то читаем этот регион // if (Mbi.State = MEM_COMMIT) and not ((Mbi.Protect and PAGE_GUARD) = PAGE_GUARD) then begin // // Это демонстрационная программа, поэтому здесь выделяется буфер под весь регион. // Регион может быть достаточно большим, поэтому лучше читать его блоками для экономии // памяти. Но здесь для простоты алгоритма вся оптимизация похерена. // GetMem(Buf, Mbi.RegionSize); try // // Читаем весь регион в выделенный буфер // if ReadProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead) then begin // // Ищем значение типа DWORD в буфере // for I := 0 to BytesRead - SizeOf(Value) do begin if PDWord(@Buf[I])^ = Value then // Найдено, выводим WriteLn('Value ' + IntToStr(Value) + ' found at ' + IntToHex(Integer(Cardinal(Mbi.BaseAddress) + I), 8)); end; end else WriteLn('Failed to read process memory ' + IntToStr(GetLastError));
finally FreeMem(Buf); end; end;
// Вычисляем адрес следуюшего региона Addr := Addr + Mbi.RegionSize; end;
finally CloseHandle(ProcessHandle); end else WriteLn('Failed to open process'); end.
а вот программа, в которой ведем поиск для примера:
program someprog;
{$APPTYPE CONSOLE}
uses SysUtils;
var SomeValue: Integer; begin SomeValue := 12345; WriteLn('One variable of this program has a value ' + IntToStr(SomeValue)); WriteLn('Press any key to exit'); ReadLn; end. |
Автор Rouse_
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Создайте форму и разместите на ней два компонента ListBox.
Скопируйте код, показанный ниже.
Запустите SysEdit.
Запустите форму Delphi. Первый ListBox должен содержать список всех запущенных приложений. Дважды щелкните на SysEdit и нижний ListBox покажет дочернее MDI-окно программы SysEdit.
Paul Powers (Borland)
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Code: |
unit Unit1; {©Drkb v.3}
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); end;
PTokenUser = ^TTokenUser; TTokenUser = record User: array[0..0] of TSIDAndAttributes; end;
procedure ConvertSidToStringSid(SID: PSID; var StringSid: LPSTR); stdcall; external advapi32 name 'ConvertSidToStringSidA';
var Form1: TForm1;
implementation
{$R *.dfm}
function GetCurrentUserSID: String; var TokenHandle: THandle; TokenInformationClass: TTokenInformationClass; TokenInformation: PTokenUser; ReturnLength: DWORD; StringSid: LPSTR; begin Result := ''; if OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, TokenHandle) then try TokenInformationClass := TokenUser; GetTokenInformation(TokenHandle, TokenInformationClass, nil, 0, ReturnLength); if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin TokenInformation := GetMemory(ReturnLength); if TokenInformation <> nil then try if GetTokenInformation(TokenHandle, TokenInformationClass, TokenInformation, ReturnLength, ReturnLength) then begin ConvertSidToStringSid(TokenInformation^.User[0].Sid, StringSid); Result := StringSid; end; finally FreeMemory(TokenInformation); end; end; finally CloseHandle(TokenHandle); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(GetCurrentUserSID); end;
end. |
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Code: |
var Hinst : THandle; WndArr : array of THandle; Wnd : THandle;
......
Procedure KillDelphiWndTimers(const AppCaption:string); var i : integer; function GetTimerWindows(Handle: HWND; Info: Pointer): BOOL; stdcall; const sClName ='TPUtilWindow'; var s : String; begin Result := True; SetLength(s,Length(sClName)+1); GetClassName(Handle, PChar(s),Length(s)); SetLength(s,Length(sClName)); // E?aeo caieoeaaou neaie #0 :) if (GetWindowLong(Handle, GWL_HINSTANCE) = Hinst ) and (s=sClName) then begin SetLength(WndArr,High(WndArr)+2); WndArr[High(WndArr)]:=Handle; end; end;
begin Wnd:=FindWindow(nil,Pchar(AppCaption)); if Wnd=0 then Exit; hinst:=GetWindowLong(Wnd, GWL_HINSTANCE); EnumWindows(@GetTimerWindows,0); for i:=0 to High(WndArr) do KillTimer(WndArr[i],1); end; |
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Code: |
function GetModuleFileNameExW(hProcess:THandle; hModule:HMODULE; lpFilename:PWideChar; nSize:DWORD):DWORD; stdcall; external 'PSAPI.DLL';
function WindowGetEXE(wnd:HWND):string; var wt:array[0..MAX_PATH-1] of WChar; r:integer; prc:THandle; prcID:cardinal; begin result:=''; if GetWindowThreadProcessID(wnd,prcID)<>0 then begin prc:=OpenProcess(PROCESS_ALL_ACCESS,false,prcID); if prc<>0 then try r:=GetModuleFileNameExW(prc,GetWindowLong(wnd,GWL_HINSTANCE),wt,MAX_PATH*2); if r=0 then r:=GetModuleFileNameExW(prc,0,wt,MAX_PATH*2); if r<>0 then result:=wt; finally CloseHandle(prc) end end end;
function SetProcessDebugPrivelege:boolean; var hToken:THandle; tp:TTokenPrivileges; rl:cardinal; begin result:=false; if not OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES,hToken) then exit; try if not LookupPrivilegeValue(nil,'SeDebugPrivilege', tp.Privileges[0].Luid) then exit; tp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED; tp.PrivilegeCount:=1; result:=AdjustTokenPrivileges(hToken,false,tp,0,nil,rl) and (GetLastError=0) finally CloseHandle(hToken); end end;
procedure TForm1.FormCreate(Sender: TObject); begin SetProcessDebugPrivelege; end;
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(WindowGetExe(hWnd)) end; |
PS только для NT4 и выше. Для Win9x юзать GetWindowModuleFileName.
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Приложение может проверить, если окно отвечает на сообщения путем отправки сообщения WM_NULL с функцией SendMessageTimeout
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Она может брать текст, где этого не может делать GetWindowText(), вот собственно и все!
Должна работать на всех win, но небыло возможности проверить.... =)
Так что кому надо... Отдельное спасибо .alex'у
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Code: |
//////////////////////////////////////////////////////////////////////////////// // // Автор: Александр (Rouse_) Багель
// Данный код приведен лишь для демонстрации // А простой вариант поиска Handle Ричедита выглядит так // var // Handle : HWND; // begin // Handle:= FindWindowEx(FindWindow(Название формы например 'Form1',nil), 0, Название элемента например 'Button1', nil), 0, true);
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls;
type TMainForm = class(TForm) TreeView1: TTreeView; procedure FormCreate(Sender: TObject); procedure Sys_Windows_Tree(Node: TTreeNode; Handle: HWND); end;
var MainForm: TMainForm;
implementation
{$R *.DFM}
//////////////////////////////////////////////////////////////////////////////// // // Стартовая функция, запускаем рекуссию используя хэндл рабочего стола //
procedure TMainForm.FormCreate(Sender: TObject); var StartHandle : THandle; begin //Если требуется найти только данные по одному приложению //замени 2 строки в функциях их закоментированными аналогами StartHandle := GetDeskTopWindow; //StartHandle := 67324;//FindWindow(PChar(Caption), nil); //На примере Винампа Sys_Windows_Tree(nil, StartHandle); end;
//////////////////////////////////////////////////////////////////////////////// // // Рекурсивная функция, строит дерево всех открытых окон, кнопок, едитов и т.д. // В качестве входных данных получает узел дерева и Хэндл окна //
procedure TMainForm.Sys_Windows_Tree(Node: TTreeNode; Handle: HWND); const MAX = 128; var TmpArray : array[0..MAX - 1] of Char; Result : String; szFileName : array[0..255] of Char; iSize : Integer; PID: Cardinal; begin //Запускаем цикл пока не закончатся окна while Handle <> 0 do begin //Получаем имя класса окна GetClassName(Handle, @TmpArray, MAX); Result := String(TmpArray); //Получаем текст (Его Caption) окна GetWindowText(Handle, @TmpArray, MAX); // Получаем имя модуля if GetwindowModuleFilename(Handle, szFileName, SizeOf(szFileName)) = 0 then ZeroMemory(@szFileName[0], 256); GetWindowThreadProcessId(Handle, PID); Result := Result + ' [' + String(szFileName) + '] (' + String(TmpArray) + '): Handle = '+ IntToStr(Handle) + ', PID = ' + IntToStr(PID); //В следующей процедуре, в скобках, добавляем результат //в дерево, получаем хэндл дочернего окна и с результатами //выполнения этих двух функций выполняем процедуру Sys_Windows_Tree Sys_Windows_Tree(TreeView1.Items.AddChild(Node, Result), GetWindow(Handle, GW_CHILD)); //Получаем хэндл следующего (не дочернего) окна Handle := GetNextWindow(Handle, GW_HWNDNEXT); //Handle := 0; end; end;
end. |
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Как мне программно нажать ALT + буква(VK_...) в другом приложении. Хендл я нашел, деляю так
SendMessage(Handle_, WM_KEYDOWN, VK_MENU,0);
SendMessage(Handle_, WM_KEYDOWN, VK_F1,0);
SendMessage(Handle_, WM_KEYUP, VK_F1,0);
но у меня не получается, что не так?
Попробуй так
Code: |
SendMessage(Handle,WM_KEYDOWN,Byte(C),$20000001); |
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Требуется нажать в "другом" приложении пару кнопок (button). (кнопки не имеют hotkeys). Ищу окно так (Дельфи):
Code: |
if FindWindow(nil, 'Advanced Dialer')<> 0 then ShowMessage('OK'); |
- Подробности
- Родительская категория: Windows
- Категория: Работа с чужими процессами
Страница 3 из 4