Delphi mesterek, horgok - a végrehajtás szempontjai

Horgok - a végrehajtás szempontjai.

Csak néhány rezervátumot szeretnék tenni: a jövőben csak 32 bites Windows és globális csapdák fognak megyni, mert a programozás során a legtöbb hiba történik; minden példa a Delphi-n lesz, mert a C ++ szerelmeseinek példái és leírása elég.

Egy további elbeszélés feltételezi, hogy az olvasó ismeri a DLL-vel való együttműködés alapelveit, és legalábbis általánosan felvázolja az írási mechanizmust.

Mi történik a rendszerben, amikor "beállítunk" egy csapdát és mi ez általában egy csapda.

A horog olyan Windows-mechanizmus, amely lehetővé teszi az alkalmazáshoz rendelt események lehallgatását, mielőtt ezek az események elérik ezt az alkalmazást.

A funkcionális szűrők olyan funkciók, amelyek értesítést kapnak egy csapda által okozott eseményről.

A csapda típusától függően a szűrőfunkciók módosíthatják az eseményeket, törölhetik őket, vagy egyszerűen reagálhatnak rájuk. Így, amikor azt mondjuk, hogy "állítsuk be a csapdát", azt értjük, hogy a szűrő funkciót a választott csapdához csatlakoztattuk. Tehát, amikor programunkban a SetWindowsHookEx funkciót használjuk, csatoljuk a szűrőfunkciót, a mutatót, amelyhez a második paramétert adjuk át, például:
SetWindowsHookEx (WH_SHELL, @ ShellHook.HInstance, 0); Ebben az esetben a ShellHook a szűrőfunkció. Később a "csapdába helyezés" kifejezés alatt azt értjük, hogy a szűrőfüggvényt egy csapdába helyezzük.

Mi történik, miután globális csapdát állítunk fel. A következő bekezdés megértése kulcsfontosságú a DLL-ben található Windows csapdák mechanizmusának megértéséhez. Ha nem érted, menj vissza és olvass el újra, és így tovább, amíg minden világossá válik.

A programozónak gondoskodnia kell arról, hogy az üzenet eljutott n-1 horoghoz (n-1 kampó). Ebben a szakaszban gyakran fordulnak elő hibák.

Hívja fel a következő csapda a lánc csapdák használt Windows CallNextHookEx funkció, az első paraméter egy fogantyú az aktuális csapda, szerezzen be egy függvény SetWindowsHookEx. Most figyeljen: tűztünk csapda folyamatában1, azaz SetWindowsHookEx funkciója a DLL, található AP folyamatában1 (lásd. 1. ábra), és ennek megfelelően, a fogantyú által visszaadott telepített csapda SetWindowsHookEx tartozik DLL adatok tartózkodó AP folyamatában1. Hagyja Process2 esemény történik, amely a beállított csapdát, majd DLL az első eljárási vetített AP Process2 egy DLL adatok Process2 inicializálni újra és kiderül, hogy Process2 változó, ahol a „hazug” leíró sor csapdák folyamatában1, egyenlő lesz 0. a függvény szűrő Process2, teljesítettek volna, hogy üzenetet küldjön le a láncot a csapdák, azaz CallNextHookEx olyan funkciót, az első paraméter az, hogy a jelenlegi leíró csapdák, de nincs DLL ebben leíró adatok található Process2 (változó, hogy tartalmaznia kell tartalmaz nulla). „Hogyan lehet egy ilyen esetben. Honnan tudjuk kezelni egy csapda a másik folyamat, ha a folyamatok önmagukban nem tudják egymásról semmit?” - kérdezed. Ebben a kérdésben én válaszolok később, de most menjünk át a fajta felület csapdákat, bár tájékoztatás a fajta teljesen meghatározott SDK.

Mint már tudjuk, a horog a Win32 API beállítása SetWindowsHookEx () segítségével történik:

funkció SetWindowsHookEx (idHook: egész; lpfn: TFNHookProc; hmod: HINST; dwThreadID: DWORD): HHOOK; stdcall;
idHook. leírja a telepítendő csapda típusát. Ez a paraméter a következő értékek valamelyikét eredményezheti:

A héj alkalmazás szűrő. A csapda szűrő funkciót akkor hívják meg, ha a legfelső szintű ablakokat létrehozzák és megsemmisítik, vagy ha a shell alkalmazásnak aktívnak kell lennie.

A csapda szűrő funkciójának mindegyik paramétere a beállított csapda típusától függően változik. A paraméterértékek részletesebb magyarázata a Win32 API súgójában található.

HM. Ennek a paraméternek tartalmaznia kell a hInstance értéket az EXE vagy a DLL fájlokban, amelyek tartalmaznak egy függvény-szűrőcsapot (emlékezzünk arra, hogy ez egy visszahívási funkció). Ha globális csapdákról beszélünk, akkor ez a paraméter csak akkor fogadhat el egy DLL-leírót, amelyből csapdát állítottak be. Ennek oka nyilvánvaló - az EXE-fájlt nem lehet másik AP-hez leképezni, míg a DLL-fájlokat kifejezetten erre a célra készítették. Hangsúlyozom ezt a körülményt: a globális csapdák csak a DLL-ben találhatók, de nem az EXE fájlokban.

dwThreadID. Ez a paraméter azonosítja azt a szálat, amellyel a csapda csatlakozik. Globális csapdákról beszélünk, tehát ez a paraméter mindig 0 lesz, ami azt jelenti, hogy a csapda a rendszer összes szálához kapcsolódik.

Visszatérési érték: a SetWindowsHookEx függvény visszaadja a telepített horog leíróját, ezt a leírót a megjelenített DLL minden példányára rendelkezésre kell bocsátani. Ezt megtegyem, majd egy kis példa után elmondom Önnek, bemutatva a gyakorlatban, hogy meg kell őrizni a fogantyú fogantyúját, hogy képes legyen felhívni az előző csapdát a láncban.

Megjegyzés. Különböző típusú csapdák telepítésekor a rendszer két láncot hoz létre. Ie minden típusú csapda saját lánccal rendelkezik. Ezért a WH_MOUSE és a WH_KEYBOARD horgok telepítésekor mindkét csapda különböző láncokban lesz, és ennek megfelelően egymástól függetlenül kerül feldolgozásra.

A szűrőfunkció eltávolítása a sorból, az UnhookWindowsHookEx funkciót kell hívnia. Ez a funkció elfogadja a SetWindowsHookEx funkció által elért horgasleírást. Ha a törlés sikertelen, a függvény nulla értéket ad vissza, ellenkező esetben az érték nem nulla. A jövőben az "eltávolítani a csapdát" kifejezés alatt a szűrő funkció eltávolítását értjük.

Most, hogy tudod, hogyan kell beállítani a csapdát és hogyan kell lőni, nézzünk meg néhány példát, amelyek vizuális ábrázolást adnak az AP folyamatok elkülönítéséről és az egyik leggyakoribb hibára mutatnak.

Most azt hiszem, hogy megértsék a forráskód könyvtárak az első példa, rájössz, hogy ne írjon egy DLL, ahonnan telepíti globális horgot. Képzeljük el, hogy egy felhasználó használja a programot, amely magában foglalja a globális horog, egy program futtatása, ami szintén létre ugyanolyan csapdába, hogy a tiéd, de telepíteni a sorban, ebben az esetben, ha az utóbbi, a második program lesz írásbeli rossz - a program nem fog működni, mert a csapda fog küldeni egy üzenetet az elülső kamera. Ez egy példa arra, hogy milyen alacsony színvonalú munkát az egyik programozó tudja elrontani a kiváló munkát végzett mindkettő.

Most néhány szó a szoftverek végrehajtásáról a fentiekből.

Fájlmegjelenítő objektumot hoz létre. Ez a funkció egy fogantyút visz a fájlmegjelenítő objektumhoz.

Ez a funkció bezárja a memóriában megjelenített fájlt, és kiadja a leíróját. Ha a függvény sikeres, akkor a függvény nem nulla értéket ad, és 0 hiba esetén.

A fent ismertetett funkciók paramétereivel kapcsolatos részletes információkért kérjük, olvassa el az SDK-t, valamint olvassa el a példát, amelyet az alábbiakban ismertetünk.

Megjegyzés. a CreateFileMapping () függvény első paraméterének meg kell jelennie a fájlleírónak. mert meg fogjuk jeleníteni az adatokat a lapozófájlban, akkor a $ FFFFFFFF vagy a DWORD (-1) értéket kell megadnunk, ami azonos értéknek felel meg; de mert a 64 bites rendszerek kora érkezik, érdemes használni az INVALID_HANDLE_VALUE értéket, amely $ FFFFFFFFFFFFFFFFF lesz a 64 bites rendszerben. Azok számára, akik a korábbi Delphi verziókról a későbbiekre váltottak (például a Delphi2-ről a Delphi4-re), azok a programjaikban ilyen problémákkal találkozhatnak.
Mivel létre fog hozni egy megnevezett fájlmegjelenítő objektumot, a CreateFileMapping () függvény utolsó paramétere az az objektum neve, amely később más folyamatokat használ, hogy azonos memóriaterületre hivatkozzon. Meg kell említeni, hogy az így létrehozott objektumnak rögzített méretűnek kell lennie, azaz. Nem változtathatja meg a program során.

Most rendelkeznek a szükséges ismeretekkel a figyelmet a második példa. 2. példa Nyissa meg a mappát, és ugyanazokat a lépéseket, mint az első példában, miután gondosan véghezvinni a forráskódot. Futtatása után az alkalmazás és állítsa a kettő-szűrő funkció az azonos típusú, próbálja jobb klikk bármelyik ablakok és látni fogod, hogy már teljesíti mindkét készlet csapdák, nem számít, melyik az ablakok nem volt egy kattintással (azaz, bár a DLL példány a hívást CallNextHookEx () függvény). Így, amikor bármely alkalmazás megjeleníti annak AP DLL, amely a szűrő funkciót, DLL ebben az esetben hozzáférése lesz az adatok leképezett a memóriába a folyamatában1 vagy Process2, attól függően, hogy a DLL. Úgy gondolom, hogy miután egy ilyen részletes magyarázatot minden tisztának kell lennie.

Köszönöm Yuri Zotovnak a támogatást.

Archívum példákkal a cikkhez: example.zip

Használt irodalomjegyzék:

  1. Microsoft Win32 szoftverfejlesztő készlet.
  2. Steve Teixeira és Xavier Pacheco, "Delphi5 fejlesztői útmutató: 1. kötet, alapvető módszerek és technológiák".
  3. Kyle Marsh, "Hooks in Win32" (az eredetiben).
  4. Dr. Joseph M. Újonc, "Horgok és DLL-k" (az eredetiben).

Moszkvai Energetikai Intézet (Műszaki Egyetem)
Atomerõmû Kar
27/2/02