Strona g│≤wna

 
1. Jak napisac odpowiednik unixowych PS i KILL ?
2. Jak pobrac liste wszystkich okien w systemie ?
3. Jak pobrac text okna ?
4. Jak odpalic nowy watek ?
5. Jak czytac pamiec procesu ?
6. Co to jest HDC [Device Context] ?
7. Jak rysowac po dowolnym oknie ?
8. Jak rysowac po pulpicie ?
9. Jak otrzymac obraz dowolnego okna ?
10. Jak ukryc proces w systemie ?
11. Jak zmieniac rozmiar i polozenie okien myszka ?
12. Jak okreslic dostepne w systemie fonty ?
13. Jak pisac programy sieciowe ?
14. Jak skonstruowac wlasny pakiet IP [SOCKET_RAW] ?
15. Jak uzyskac informacje o systemie ?
16. Jak uruchomic program przy starcie systemu ?
17. Jak odpalic inny proces ?
18. Jak odpalic domyslna przegladarke lub klienta poczty ?
 



1. Jak napisac odpowiednik unixowych PS i KILL ?
proponuje na poczatek przyjrzec sie unitowi: TLHelp32. Juz ? Ok.


{BEGIN OF PS.PAS}
unit PS;

interface
uses
windows,sysutils,tlhelp32,classes;

function MyPS:TStringList;
function MyKILL(pid:integer):boolean;

implementation

{A oto PS}
function MyPS:TStringList;
var
  sHandle:thandle;pEntry:tprocessentry32;
begin
  sHandle:=createtoolhelp32snapshot(TH32CS_SNAPPROCESS,0);
  pEntry.dwSize:=sizeof(pEntry);
  Result:=TStringList.create;
  if integer(process32first(sHandle,pEntry))<>0 then 
  repeat
    Result.Append(inttostr(pEntry.th32ProcessID)+':  '+pEntry.szExeFile);
  until integer(process32next(sHandle,pEntry))=0;
  closehandle(sHandle);
end;
{Koniec PS'a}

{A oto KILL}
function MyKILL(pid:integer):boolean;
var
  sHandle:thandle;
begin
  try
    sHandle:=openprocess(PROCESS_TERMINATE,bool(0),pid);
    if integer(terminateprocess(sHandle,0))=0 then result:=false else result:=true;
  except end;
end;
{Koniec KILL'a}

end.
{END OF PS.PAS}


2. Jak pobrac liste wszystkich okien w systemie ?

Oto przykladowe procedury, ktore wykonuja iteracje po wszystkich oknach w systemie okreslajac ich klase (class) oraz text. Dane zostana wpisane do struktury List:TStringList ktora musi najpierw zostac zainiciowana.

function EnumChildProc(Hw:Hwnd;P:pointer):boolean;stdcall;
var
winname,cname:array[0..144]of char;
begin
result:=true;
getwindowtext(hw,winname,144);
getclassname(hw,cname,144);
List.Append('POTOMEK:  TEXT:'+strpas(winname)+'   KLASA: '+strpas(cname));
end;

function EnumWindowProc(Hw:HWnd;P:Pointer):boolean;stdcall;
var
winname,cname:array[0..144]of char;
begin
result:=true;
getwindowtext(hw,winname,144);
getclassname(hw,cname,144);
List.Append('OKNO:     TEXT:'+strpas(winname)+'   KLASA: '+strpas(cname));
enumchildwindows(hw,@enumchildproc,0);
end;

aby rozpoczac iteracje wykonujemy:

enumwindows(@enumwindowproc,0);



3. Jak pobrac text okna ?
Sluzy do tego celu funkcja getwindowtext.

GetWindowText(hw,BUFOR,DL_BUFORA);

gdzie: hw - uchwyt okna, BUFOR - tablica znakow, DL_BUFORA - max. dlugosc wczytanego ciagu. np.: GetWindowText(form1.handle,BUFOR,DL_BUFORA) - zwroci nam form1.caption

4. Jak odpalic nowy watek ?
Najprosciej mozna to zrobic w ten sposob:

procedure WkurzajUsera;
begin
	repeat beep;sleep(1000);until false;
end;

//i podczepiamy nasza procedurke jako watek

CreateThread(nil,0,@WkurzajUsera,nil,0,x);

(x:integer)

win32.hlp:
HANDLE CreateThread(

    LPSECURITY_ATTRIBUTES  lpThreadAttributes,	// address of thread security attributes  
    DWORD  dwStackSize,	// initial thread stack size, in bytes 
    LPTHREAD_START_ROUTINE  lpStartAddress,	// address of thread function 
    LPVOID  lpParameter,	// argument for new thread 
    DWORD  dwCreationFlags,	// creation flags 
    LPDWORD  lpThreadId 	// address of returned thread identifier 
   );



5. Jak czytac pamiec procesu ?
Aby moc przeczytac pamiec procesu nalezy miec jego uchwyt, pozniej ustawic go w tryb do odczytu i podac miejsce gdzie maja trafic dane przeczytane z pamieci.

function ReadProcMem(var path,buf:PChar;length:integer):integer;
var ProcInf:TProcessInformation; //tutaj otrzymamy identyfikatory procesu i watku glownego
    StartInf:TStartupInfo; //tutaj nieistotne
begin
fillchar(StartInf,sizeof(StartInf),0); //ta struktuta nie bedzie uzywana
fillchar(Buf,length,0); //czyscimy bufor
Result:=0;
CreateProcess(path,nil,nil,nil,false,0,nil,nil,StartInf,ProcInf); //tworzymy nowy proces
OpenProcess(PROCESS_VM_READ,false,ProcInf.dwProcessId); //otwieramy go z flaga do odczytu
ReadProcessMemory(ProcInf.hProcess,nil,Buf,length,result); //czytamy length bajtow z pamieci
TerminateProcess(ProcInf.hProcess,0); //wykanczmy proces z flaga wyjscia 0
end;


6. Co to jest HDC [Device Context] ?
Device Context [w Delphi typ HDC] jest struktura, ktora definiuje obiekty graficzne i ich atrybuty np. kolor, szerokosc i styl pedzla, styl wypelniania, bitmape uzywana do odrysowywania ekranu, palete uzywana do ustawiania dostepnych kolorow itp. Do DC nie ma dostepu bezposredniego mozna go uzyskac przez odpowiednie funkcje.

Co to oznacza w praktyce ? DC jest bazowa sruktura dla obiektu typu Canvas, ktory owija ja w metody i wlasciwosci Delphi.


7. Jak rysowac po dowolnym oknie ?
Musimy znac jego uchwyt.

Canvas.HAndle:=GetWindowDC(znane_okno.handle); 
{tutaj mozmy rysowac na Canvas}
ReleaseDC(znane_okno.handle,canvas.handle);//pozniej musimy jeszcze zwolnic uchwyt


8. Jak rysowac po pulpicie ?

Pulpit mozna traktowac jak zwykly Canvas.
GetDesktopWindow - zwraca uchwyt pulpitu.
Canvas.Handle:=GetWindowDC(GetDesktopWindow {w Win95 moze byc poprostu 0}); dalej tak jak wyzej.


9. Jak otrzymac obraz dowolnego okna ?
Oczywiscie ta procedura dziala tylko dla obiektow pochodnych od TWinControl (handle)

function Control2Bitmap(Obj:TWinControl):TBitmap;
begin
  Result:=Tbitmap.create;
  Result.Height:=Obj.Height;
  Result.Width:=Obj.Width;
  Result.Canvas.Handle:=CreateDC(nil,nil,nil,nil);
  Result.canvas.lock;
  Obj.PaintTo(Result.Canvas.Handle,0,0);
  result.canvas.unlock;
  DeleteDC(result.canvas.handle);
end;

teraz mozemy sobie zapisac to do pliku czy zrobic cokolwiek innego co umozliwia TBitmap;


10. Jak ukryc proces w systemie ?
Mozna to zrobic na pare sposobow. Pierwszy jest bardzo prosty - nazwac plik .exe (bez nazwy), drugi rownierz - wpisujemy w application.title:='' ale co jesli program nie ma interfejsu application (np. konsolowy) - istnieje bardzo ciekawa funkcja systemowej biblioteki kernel32.dll

function registerserviceprocess(pid,blah:longint):boolean;
stdcall;external 'kernel32.dll' name 'RegisterServiceProcess';

no i teraz tylko:

registerserviceprocess(0,1);

raczej sie nie pokaze po ctrl+alt+del


11. Jak zmieniac rozmiar i polozenie okien myszka ?
Pierwowzor odpowiedzi byl w tipsach na BSC, troche poeksperymentowalem z WM_SYSCOMMAND oraz jej parametrami, otoz mozna przesuwac i rozszerzac kontrolki ktore maja uchwyt czyli pochodza od TWinControl (np. TImage, TShape i TLabel nie mozna)

Wartosci parametru POS:
{SC_ZIZE=61440}
SC_SIZE + 1 - lewo
SC_SIZE + 2 - prawo
SC_SIZE + 3 - g≤ra
SC_SIZE + 4 - lewo+g≤ra
SC_SIZE + 5 - prawo+g≤ra
SC_SIZE + 6 - d≤│
SC_SIZE + 7 - lewo+d≤│
SC_SIZE + 8 - prawo+d≤│ [standardowe]
SC_SIZE + 9 - przenoszenie kontrolki
SC_SIZE + 10 - brak
SC_SIZE + 11 - [myszka prawo+g≤ra] lewo+d≤│
SC_SIZE + 12 - [myszka d≤│] prawo
SC_SIZE + 13 - brak
SC_SIZE + 14 - [myszka g≤ra] lewo
SC_SIZE + 15 - [myszka d≤│] prawo
SC_SIZE + 16 - brak
SC_SIZE + 17-31 - przenoszenie kontrolki
SC_SIZE + 32 - minimalizacja {O to, jest bardzo ciekawe, mozna sobie zminimalizowac button ;-)}

a teraz w zdarzeniu OnMouseDown:

ReleaseCapture;
POS:=SC_SIZE + 9; {przenoszenie kontrolki}
TControl(self).Perform(WM_SysCommand,POS,0);


12. Jak okreslic dostepne w systemie fonty ?
Zrobi to za nas funkcja EnumFonts, ktora do iteracji po wszystkich fontach danego urzadzenia uzywa funkcji zwrotnej (patrz pyt. 2).

funkcja zwrotna ma postac: 

function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
begin
  Form1.memo1.lines.append(LogFont.lfFaceName); //tutaj np. dodajemy nazwy fontow do listy
  Result := 1; // jesli chcemy przerwac iteracje musimy jako result podac 0
end;

procedure TForm1.Button1Click(Sender: TObject);
var DC:HDC;
begin
DC:=GetDC(0); //device context pulpitu, jesli chcemy fonty drukarki podaemy printer.handle
enumfonts(DC,nil,@EnumFontsProc,nil); //podajemy adres naszej funkcji
end;


13. Jak pisac programy sieciowe ?
Po szczegoly odsylam do komponentow na DSP [query:socket] i do literatury, tutaj przyblize kilka funkcji pozwalajacych w najprostszy sposob wysylac i odbierac dane.

Najpierw musimy dysponowac gniazdkiem (socketem) przez ktore bedziemy mogli sie komunikowac, kazde gniazdko okreslone jest 6 wspolczynnikami : port lokalny, port docelowy, adres lokalny, adres docelowy, protokol (tcp lub udp, my zajmiemy sie tcp), aktywne / pasywne.

gniazdko w systemie widziane jest jako zwykla liczba typu integer, jest to w zasadzie uchwyt okna istnieja 2 podstawowe funkcje ktore go zwracaja: socket i accept.

funkcja socket tworzy nowe gniazkdo, jej przykladowe uzycie:

SSOCK:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

uzycie accept jest troche bardziej zlozone, najpierw musimy miec zwykle gniazdko utworzone przez socket, nastepnie przypisujemy temu gniazdku port lokalny i ustawiamy je w tryb sluchania funkcja listen, funkcja accept uzywa 'sluchajacego' gniazdka do utworzenia calkowicie nowego polaczenia z komputerem ktory laczy sie z nami (my jestesmy serverem a on klientem).

SSOCK,CSOCK:integer;

procedure make_listen_socket;
var
addr,taddr:tsockaddrin;
sock,size:integer;
begin
  fillchar(addr,sizeof(addr),0);
  fillchar(taddr,sizeof(taddr),0);
  fillchar(maddr,sizeof(maddr),0);

  SOCK:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); // jesli socket=-1 to blad!

  addr.sin_family:=AF_INET;
  addr.sin_addr.s_addr:=htonl(INADDR_ANY);
  addr.sin_port:=htons(666);  //przypisujemy gniazdku port lokalny
  bind(SOCK,addr,sizeof(addr)); //jesli bind<>0 to blad !
  listen(SOCK,5); //jesli listen<>0 to blad !

  repeat
     sleep(1000);
     size:=sizeof(taddr);
     CSOCK:=accept(SOCK,@taddr,@size);
  until csock>0; //az ktos sie z nami polaczy
end;

function connect_to_destination(DESTINATION_HOST:string;DESTINATION_PORT:integer):integer;
var
	addr:tsockaddrin;
	he:phostent;
	mode:integer;
begin

  SSOCK:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  fillchar(addr,sizeof(addr),0);
  
  addr.sin_family:=AF_INET;
  addr.sin_addr.s_addr:=inet_addr(@DESTINATION_HOST[1]); //moze byc pchar(DESTINATION_HOST)
  addr.sin_port:=htons(DESTINATION_PORT);

  he:=gethostbyname(@DESTINATION_HOST[1]); //wywolujemy resolver
  if he<>nil then move(he^.h_addr_list^^, addr.sin_addr.s_addr, he^.h_length)
  
  result:=connect(SSOCK,addr,sizeof(addr));
end;


//ta funkcja wysle nam cos przez gniazdko
function say(gniazdko:integer;co:string):integer;
begin
result:=send(gniazdko,co[1],length(co),0);
end;

//ta funkcja odbierze nam cos przez gniazdko do bufora 'gdzie' ('ile' bajtow)
function hear(gniazdko:integer;var gdzie:string;ile:integer):integer;
begin
result:=recv(gniazdko,gdzie[1],ile,0);
end;



14. Jak skonstruowac wlasny pakiet IP [SOCKET_RAW] ?
Niestety nie da sie tego poki co zrobic za pomoca funkcji winsocka, tzn. nie jest udostepniony ten tryb. Co prawda w winsocku 2.x+ teoretycznie mozna tworzyc SOXKET_RAW ale nie da sie skonstruowac wlasnego pakietu, tak wiec poki co zabawe w spoofing i inne unixowe dobrodziejstwa trzeba odlozyc.

btw. jak ktos jest zainteresowany napisaniem odpowiedniego vxd do obslugi czegos takiego to niech napisze na priva.



15. Jak uzyskac informacje o systemie ?
Istnieje cala grupa funckji WinAPI ktora to umozliwia, tutaj przytocze krotki opis.

InitiateSystemShutdown - rozpoczyna zamykanie systemu
AbortSystemShutdown - anuluje zamykanie systemu
ExpandEnvironmentStrings - pobiera zmienne srodowiskowe
GetComputerName - nazwa komputera
GetKeyboardType - typ klawiatury
GetSysColor - podaje kolor dla wybranego elementu systemu
GetSystemDirectory - katalog systemowy
GetSystemInfo - zwraca strukture zawierajaca informacje o architekturze systemu (typ procesora)
GetSystemMetrics - masa informacji na temat systemu, np. jak zostal uruchomiony itp.
GetThreadDesktop - zwraca uchwyt pulpitu przypisanego do podanego watku
GetUserName - zwraca nazwe uzytkownika
GetVersion - czy Windows NT czy 95
GetVersionEx - rozszerzona informacja o versji systemu
GetWindowsDirectory - katalog WINDOWS
SetComputerName - ustawia nazwe komputera jaka bedzie obowiazywac po restarcie
SetSysColors - ustawia kolor podanych elementow systemu
SystemParametersInfo - pobiera lub ustawia rozne informacje systemowe.



16. Jak uruchomic program przy starcie systemu ?
Mozna of koz przez 'Menu Start' ale jesli chcemy to zrobic dosc niewidocznie to nalezy wpisac sciezke dostepu do odpowiedniego klucza w rejestrze.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
oraz
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce


17. Jak odpalic inny proces ?
path,commandline:PChar - sciezka do pliku wykonywalnego i jego argumenty
ProcInf:TProcessInformation; //tutaj otrzymamy identyfikatory procesu i watku glownego
StartInf:TStartupInfo; //tutaj nieistotne

CreateProcess(path,commandline,nil,nil,false,0,nil,nil,StartInf,ProcInf); //tworzymy nowy proces




18. Jak odpalic domyslna przegladarke lub klienta poczty ?
Sluzy do tego funkcja ShellExecute, mozna za jej pomoca otwierac lub drukowac kazdy dokument.

ShellExecute(handle,'open','http://www.inprise.com',nil,NIL,SW_SHOWNORMAL);
otworzy nam strone Inprise w domyslej przegladarce (mailto:jankus@cavern.pl - otworzy nowy list)

ShellExecute(handle,'open','netscape','http://www.inprise.com',NIL,SW_SHOWNORMAL);
otworzy nam strone Inprise w Netszkapie

ShellExecute(handle,'print','dokument.doc',nil,nil,SW_SHOWNORMAL);
wydrukuje dokument.doc





All rights reserved. Copyright by JaNkus 1998/1999