Csapdák és szűrők létrehozása események rögzítésére a delphi, egy it-specialist blog

Egyszer régen szükségem volt egy program készítésére, amelyen screenshotok készültek. Nevezetesen a felhasználó kiválasztja a szükséges területet a képernyőn az egérrel, majd kiadja a gombot és kap egy képernyőképet. Abban az időben nem tudtam a csapdákról. Néhány napig "küzdöttem" a feladat fölött, de a kísérleteim nem vezetett semmihez, ők nem. Miután elolvastam a különböző irodalmat és cikkeket, és megtanultam, milyen csapdák vannak, és mit "eszik", elkezdtem kísérletezni tovább. És elkezdtem Mikhail Flenov "A Delphi programmal a hacker szemével" című könyvvel. Abban az időben, az összes dolog, amit meg kell felhívni a könyvéből, úgy tűnt nekem, nagyon könnyen, de aztán rájöttem, (mint ebben az esetben, hogy tapasztalat), ami nagyon téved.

De történt egy csoda. Juri Revich kezébe került a "Nem szabványos programozási technikák Delphivel" című könyve. A kiöntést, ami egy kicsit megdöbbentett, itt van az, amire szükségem van. Ahelyett, hogy kiderült volna korábban, mert szükséges átadni értékeket a csapda a MAP fájlokat (Memory Mapped Files) - fájlmegjelenítés a tárhelyen.

Nos, elkezdünk kémeket írni?

Így minden fokozatosan ...
A Microsoft Windows operációs rendszerben a csapda egy speciális eseményfunkció (például üzenetek, egér vagy billentyűzetbevitel) lehallgatásának mechanizmusa, mielőtt elérik az alkalmazást. Ez a funkció ezután válaszolhat az eseményekre, és egyes esetekben módosíthatja vagy törölheti azokat. Az eseményekről értesítő funkciókat szűrési funkciónak nevezik, és különböznek az általuk elfogott események típusaiban. Például egy szűrőfunkció, amely lefedi az összes egér vagy billentyűzet eseményt. Ahhoz, hogy a Windows hívhassa a szűrőfunkciót. ezt a funkciót telepíteni kell, azaz csapdába kell helyezni (pl. billentyűzetcsapda).

Ez elég elmélet, elkezdünk írni. Egy egyszerű keylogger írunk. Miért egyszerű? Igen, mert a kém nem csak a megnyomott billentyűket fogja el, hanem figyeli azokat az alkalmazásokat is, amelyeken ezeket a gombokat megnyomják. Akkor is rögzítheti a horog elindulási idejét, az alkalmazást, amelyen a billentyűleütések idején a bemeneti fókusz volt, és így tovább. De te magad is megteheted.
Hozzon létre egy új projektet. Dobja a TMemo-t és két gombot:

Csapdák és szűrők létrehozása események rögzítésére a delphi, egy it-specialist blog

Ezután a felhasználói üzenettel deklaráljuk az állandó értéket:

Most be kell importálnunk a csapda indításához és eltávolításához szükséges eljárásokat. Bár a könyvtár még nem írt, de így nem tér vissza. Adja hozzá a következő sorokat itt:

A következő lépésben hozza létre a kezelőket a gombokhoz, és írja be a következő kódot:

A "Start" gomb kezelőben vannak olyan változók, amelyeket még nem deklaráltunk, ezek a változók egy másik modulban vannak, amelyet később tárgyalunk.

Most meg kell adnunk egy kezelőt az egyéni üzenetünkhöz. Ehhez tegye a következő eljárás prototípust a privát területre:

Nos, maga a kezelő olyan egyszerű, hogy sehol sem könnyebb.

Az Üzenet változóban. a Wparam paraméterben. van egy virtuális kulcsazonosítójú kód. Az egész probléma az, hogy ezt a kódot nem tudjuk meghatározni, nincs semmilyen szimbólum egyetlen regiszterben sem, sokkal kevésbé a billentyűzet elrendezését, amelyen bevezetésre került. Ezért hozom a GetCharFromVKey funkciót. amely pontosan a szimbólumot adja vissza. Ebben benne van a nyilvántartás és az elrendezés is.

Maga a funkció csak a kódok kódolására szolgál. Ezért nem fogunk élni vele. Csak annyit mondok, hogy felismeri az összes karaktert az A-tól Z-ig, az a-tól z-ig, az A-tól Z-ig, és az a-tól én-ig stb. Vagyis a regiszter és az elrendezés alapján.

Most meg kell adnunk egy modulot egy közös megosztott terület létrehozásához. A modul neve IniHook. további inicializálási és végleges szakaszokkal. Hozzon létre egy új modult, és nevezze el az IniHook-ot. Két modult csatlakoztatunk: Windows és Üzenetek.

Mutasson mutatót a THookInfo változóhoz
Ezután írjon egy THookInfo rekordot.

Ezután két változót deklarálunk:

Az AdatArea változón keresztül a THookInfo rekordmezőkre hivatkozunk. A hMapArea tartalmazza a "kivetített" fájl objektumának leírását.

Ezután az inicializálási szakaszban hívja fel a CreateFileMapping funkciót, és hozzárendezze a visszatérési értéket a hMapArea változóhoz. Ezután felhívjuk a MapViewOfFile függvényt, és hozzárendeljük annak visszatérési értékét az AdatArea változóhoz. Lásd az alábbi forráskódot:

Röviden áttekintjük az itt használt funkciókat.
A fájlmegjelenítő objektumok létrehozása és használata a Windows API funkciói révén történik. Három funkció van:

  • CreateFileMapping;
  • MapViewOfFile;
  • UnMapViewOfFile.

Egy kicsit zavart? Nos, folytatjuk. Ezután meg kell adnunk egy kódot a véglegesítés szakaszban, amely eltávolítja a fájlt a memóriából.

Meg kell jegyezni, hogy az UnMapViewOfFile függvényt a CloseHandle funkció előtt kell hívni. Vagyis semmi esetre sem lehet a rendet megsérteni.

Nos, megírtuk a modult, most kapcsolódni kell a fő programhoz. Még mindig nekünk kell írni a csapdát, amely a könyvtárban lesz. Időközben kávét iszunk. Ivott? Folytatjuk. Indíts egy új projektet, nem csak egy alkalmazás írásához, hanem egy könyvtárhoz. Ehhez válassza a Fájl / Új / Egyéb parancsot, majd a következő ablak jelenik meg:

Csapdák és szűrők létrehozása események rögzítésére a delphi, egy it-specialist blog

Keresse meg a DLL varázsló elemet, és kattintson duplán rá. És a Delphi létrehoz egy üres dinamikus könyvtári projektet. Ne felejtse el menteni azonnal. Az alábbiakban a könyvtár forráskódja található:

Most beszéljünk mindent rendben. Először, meg kell csatlakozni három modulból áll: a Windows, az Üzenetek, SysUtils, és az egyik modul, azaz IniHook úgyhogy nem őriznie a modul a katalógusban a program és a könyvtári katalógus Megvan szállítani egy megosztott könyvtár, amely tartalmazza a könyvtár, a főprogram és a könyvtár. De tud-e csatlakozni a szokásos módon, azaz, kijelentve, hogy az összes modul, de akkor meg kell tenni a modul a könyvtári katalógusban. Ez már ízlés.

Most, mint a főprogramban, az állandó WM_ReadWithHook = WM_USER + 120-at deklaráltuk felhasználói üzenetünkben. A KeyboardProc funkció a csapda kezelője. Ez a funkció három paraméterrel rendelkezik. Most részletesebben tekintünk rájuk. Ha a horog típusa WH_KEYBOARD értékre van állítva. ezek a paraméterek a következő értékekkel rendelkezhetnek:

  • ncode. Meghatározza a hurok eljárás használatának kódját az üzenet kezelésének meghatározásához. Ez a paraméter több értéket tartalmazhat.
  • AC_ACTION - A WParam és a LParam paraméterek tartalmazzák a megnyomott kulcsra vonatkozó információkat. Más típusú üzenetek, amelyeket nem kell feldolgozni.
    • WParam. Olyan kódot definiál egy virtuális kulcsazonosítóval, amely egy billentyűleütéses üzenetet generált.
    • LParam. meghatározza az ismétlődő számlálást, a szkennelési kódot, a kiterjesztett kulcsjelzőt, a kontextuskódot, a kulcs előző állapotjelzőjét és az átmeneti állapotjelzőt. Ez a paraméter lehet bizonyos értékek kombinációja. De nem vesszük figyelembe őket, mert a mi esetünkben nem nyújtanak érdeklődést.

A CallNextHookEx négy paraméterrel rendelkezik:

  1. (hhk) - a csapda fogantyúja a SetWindowsHookEx funkció által visszaadva;
  2. (Kód) - meghatározza a lehallgatási kódot;
  3. (WParam) - meghatározza a bejövő hosszúságot a csapda feldolgozási folyamatában. Az értéke attól függ, hogy milyen típusú csapdába helyezett;
  4. (LParam) - meghatározza a bejövő hosszúságot a csapda feldolgozási folyamatában. Az értéke attól függ, hogy milyen típusú csapdába helyezett.

Jelenleg ebben a sorban érdekel ez a kód:

Ebben a sorban, átadjuk a parancsot, hogy a kérelmet, amely az úgynevezett mi egyéni üzenetkezelő WM_ReadWithHook = WM_USER + 120 és a paraméterek wParam. amely tartalmazza a kulcskódot.

És végül felhívom a CallNextHookEx funkciót. A visszatérési érték, amelyre átmennek a változóhoz. Észrevettem, hogy szinte senki sem teszi ezt. Minden működik. De a játékban, például a "Counter-Strike" a csapdával bekapcsolt, volt kulcsfontosságú lóg. És miután hozzáadta a CallNextHookEx funkciót kezelőnk végéhez. minden rendben volt.
A SetHook eljárás csak egy sornyi sort tartalmaz:

Itt hívják a SetWindowsHookEx hook funkciót. Ennek a funkciónak négy paraméterrel kell rendelkeznie:

  1. A csapda típusa. Megadott WH_KEYBOARD, ez a csapda vezérli a billentyűleütéseket;
  2. A csapda eljárását tartalmazó azonosító;
  3. Mutató az alkalmazáshoz;
  4. Áramlásazonosító. Ha a paraméter nulla, akkor az aktuális értéket használjuk.

A DelHook eljárásnak csak egy kódja van:

Az UnhookWindowsHookEx funkciónak csak egy paramétere van, és ez egy csapdafogantyú.
A SetHook és a DelHook eljárások exportként jelennek meg.
Nos, ez minden. Letöltheti a demo verziót vagy a projekt teljes forrását.