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.

 

 

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_

Создайте форму и разместите на ней два компонента ListBox.

Скопируйте код, показанный ниже.

Запустите SysEdit.

Запустите форму Delphi. Первый ListBox должен содержать список всех запущенных приложений. Дважды щелкните на SysEdit и нижний ListBox покажет дочернее MDI-окно программы SysEdit.

Paul Powers (Borland)

 

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.

 

 

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;

 

 

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.

 

Приложение может проверить, если окно отвечает на сообщения путем отправки сообщения WM_NULL с функцией SendMessageTimeout

 

Она может брать текст, где этого не может делать GetWindowText(), вот собственно и все!

Должна работать на всех win, но небыло возможности проверить.... =)

Так что кому надо... Отдельное спасибо .alex'у

 

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.

 

 

Как мне программно нажать 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);

 

Требуется нажать в "другом" приложении пару кнопок (button). (кнопки не имеют hotkeys). Ищу окно так (Дельфи):

Code:

if FindWindow(nil, 'Advanced Dialer')<> 0 then

ShowMessage('OK');