Informatika | Informatikai biztonság » Mátrai Károly - Shareware és Trialware programok védelme és megkerülése

Alapadatok

Év, oldalszám:2005, 64 oldal

Nyelv:magyar

Letöltések száma:240

Feltöltve:2008. október 29.

Méret:491 KB

Intézmény:
-

Megjegyzés:

Csatolmány:-

Letöltés PDF-ben:Kérlek jelentkezz be!



Értékelések

Nincs még értékelés. Legyél Te az első!

Tartalmi kivonat

Eötvös Loránd Tudományegyetem Informatikai Kar Shareware és Trialware programok védelme és védelmük megkerülése Mátrai Károly Témavezet : Kincses Zoltán Budapest, 2005. Tartalomjegyzék 1. Bevezetés 4 1.1 A témaválasztás indoklása 4 1.2 Jogi kitekintés 4 2. Alapismeretek 7 2.1 Alapfogalmak 7 2.11 Szoftver licenc típusok 7 2.12 Eszközök és egyéb fogalmak 9 2.2 Az assembly nyelv áttekintése 10 2.21 A programozás eszközei 10 2.22 A regiszterek m ködése 11 2.23 Fontosabb utasítások 11 2.3 Disassembler m ködésének bemutatása 12 2.4 Debugger m ködésének bemutatása 14 2.5 Hexa editor m ködésének bemutatása 15 3. Védelmi és megkerülési módszerek 17 3.1 Általános védelmi módszerek 17 3.11 Jelszó 17 3.12 Sorozatszám 17 3.13 Kulcsfájl 17 3.14 Id korlát 17 3.15 Hardverkulcs 18 3.2 Általános védelmi módszerek kikerülése 18 3.21 Ini fájlok 18 3.22 Registry hack 19 3.23 Dátum visszaállítás 20 3.24 Sorozatszám

generátor 20 3.25 Kulcsgenerátor 21 3.26 Crack 21 4. A shareware programok 22 4.1 Shareware programok felépítése 22 4.2 Shareware programok védelme 23 4.3 Shareware programok védelmének megkerülése 25 4.31 Sorozatszám generátorok írása 25 4.32 Kulcsfájl elkészítése 26 4.33 Crack program írása 27 4.4 A Mirc 616 program védelmének részletes elemzése 31 4.41 Ismerkedés a program védelmével 31 4.42 Stratégiák a védelem megkerülésére 32 4.43 Kódelemzés 32 5. A trialware programok 39 5.1 Trialware programok felépítése 39 5.2 Trialware programok védelme 39 5.21 Fix napos id korlát védelem 40 5.22 Adott dátumig m köd védelem 40 5.23 Adott indítási számos védelem 40 5.3 Trialware programok védelmének megkerülése 41 5.4 Az Earth Recource Mapper 64 SP1 program elemzése 43 5.41 Ismerkedés a program védelmével 43 5.42 Felmerül stratégiák 44 2 5.43 A kód elemzése 45 5.431 Indítási szám vizsgálata 47 5.432 Lejárati

dátum vizsgálata 48 5.433 Ínyencségek 49 6. A demoware programok 51 6.1 A demoware programok felépítése 51 6.2 A demoware programok el nyei 51 6.3 A demoware programok hátrányai 51 7. Fejl déstörténet 53 7.1 Régebben használt szoftvervédelmi módszerek 53 7.2 A jöv védelmi módszere 53 8. Összefoglalás 56 9. Irodalomjegyzék és hivatkozások 57 10. Ábrajegyzék 58 11. Melléklet 59 11.1 Fontosabb Microsoft Windows API függvények listája 59 11.2 x86 Assembly utasítás készlet (Táblázat). 62 3 1. Bevezetés 1.1 A témaválasztás indoklása A szoftvergyártók termékeik népszer sítése érdekében lehet séget biztosítanak a felhasználóknak arra, hogy el zetesen kipróbálják szoftvereiket, és véleményt alkothassanak róluk. A gyártók azért kényszerültek erre a lépésre, mert a számítógépek elterjedésével egyre több ugyanazon felhasználói igényeket kielégít szoftver került a piacra. Az elterjedt szokás az lett,

hogy a szoftvereket a gyártók bárki által hozzáférhet vé tették úgy, hogy az eredeti programhoz képest a kipróbálható verzióba beépítettek néhány korlátozást. A létrejöv szoftver licenc típusok leírják, hogy az adott kategóriába sorolt program milyen körülmények között használható ingyenesen illetve térítés ellenében. A teljes verzió könnyebb terjesztése érdekében egyes programok úgy lettek megírva, hogy a kipróbálható verzióból a regisztrációs díj kifizetése után teljes verzió nyerhet a beépített korlátozások megszüntetésével. Dolgozatomban a Shareware és Trialware licenc típus alá es programokra jellemz védelmeket fogom bemutatni, mely nem zárja ki, hogy ezen védelmeket más licenc típus alá sorolt program ne használhatná. Megvizsgálom, hogy az ilyen védelmek mennyire hatékonyak, milyen módszerek ismertek megkerülésükre. A célom az, hogy a programozó tisztában legyen azzal, hogy mire számíthat a

felhasználótól akkor, ha saját programja korlátozására a tárgyalt védelmi típusok közül választ. Ha átlátja a kés bbiekben tárgyalt módszereket, akkor már a védelem írásakor fel tudja tenni magában azt a kérdést, hogy ez mennyire játszható majd ki. Így reményeim szerint hatékonyabb védelmet tud majd írni, mint amit a mostani programok használnak. Bár a dolgozat a hogyan kérdését vizsgálja, az itt leírt módszerek ismerete senkit sem jogosít fel arra, hogy azt rossz célokra használja. Minden, ami itt leírásra került csak és kizárólag tanulmányi célokat szolgál! 1.2 Jogi kitekintés A dolgozatom bevezetéseként megismerjük a programok védelmére vonatkozó jogi vonatkozásokat, ehhez az interneten elérhet jogi fórumon publikált dolgozatokból válogattam össze az ide vonatkozó részeket.[9] A számítógépi program védelme két módon valósítható meg, az egyik a technikai, a másik a jogi védelem. Az els esetben a fejleszt

informatikai eszközökkel biztosítja, hogy terméke jogosult felhasználó által legyen csak alkalmazható. A második esetben a törvényhozó a szellemi alkotás mindenkivel szembeni védelmét biztosítja jogi eszközökkel. Az új célkit zéseknek igyekezett az Országgy lés megfelelni, azzal hogy megalkotta az 1999. évi LXXVI törvényt a szerz i jogról Az új szerz i jogi törvény új megközelítésben és részletesen szabályozza a különleges helyzetben lev , és különleges alkotásnak számító számítógépi programalkotások jogi helyzetét. Lényegét tekintve a szoftver gondolati, szellemi teljesítmény eredménye, mely a számítógép fizikai m ködésének logikai modellje. A program - tudatos fejlesztés eredményeképp - utasítások folyamatos és logikus láncolata. Ugyanakkor a szoftverek védelmével foglalkozó szervek, a védelemr l rendelkez jogszabályok számos 4 országban, köztük hazánkban sem, nem rendelkeznek a szoftver szabatos

fogalmi meghatározásáról. A kontinentális jogrendszereket vizsgálva - Magyarországon is - úgy t nik a szerz i jog vált a szoftver jogi oltalmának megvalósítására általános megoldássá. E védelmi rendszer annak a ténynek elismerését jelenti, hogy az új tartalmat hordozó gondolat jogi kifejezést érdeml - értéket képvisel. A hatályos magyar szabályozás – 1999 évi LXXVI. tv a szerz i jogról (továbbiakban Szjt) - megfogalmazása szerint a törvény védi valamennyi irodalmi, tudományos és m vészeti alkotást. Ilyennek min sül a „a számítógépi programalkotás és a hozzá tartozó dokumentáció (a továbbiakban: szoftver) akár forráskódban, akár tárgykódban vagy bármilyen más formában rögzített minden fajtája, ideértve a felhasználói programot és az operációs rendszert is,”[Szjt. 1.§ (2) bek c) pontja] A kontinentális jogrendszer szerz i jogának „ikertestvére” az angolszász jogrendszerekben alkalmazott copyright

intézménye. Amiben hasonlítanak az az, hogy mindegyikben - a jogi védelem biztosítása szempontjából - kulcskérdés a szerz ség kérdése. Hasonlítanak abban is, hogy írásm ként védelmezik a szoftvert, mégis alapvet különbségek vannak, melyekre már az intézmények elnevezése is utal. A szerz i jogvédelem centrumában a szerz áll, míg a copyright esetén a jogi oltalom az alkotásra irányul, az illetéktelen másolás (copy) és terjesztés ellen nyújt védelmet. Az eredetiség, s vele a védelem indokoltsága nemcsak az önálló alkotások létrehozásakor, hanem más szerz m vének átdolgozásakor, feldolgozásakor, fordításakor is megállapítható lehet, ha a létrejöv opusnak új, eredeti jellege van, és nem sérti az átdolgozott m szerz jének jogait [Szjt. 4§ (2) bek] A számítógépi program esetében a szoftvernek az eredetit l eltér programnyelvre történ átírása tekinthet átdolgozásnak [Szjt. 58§ (2) bek] Ugyanakkor a magyar

szabályozás szerint nem részesülhet védelemben a szoftver csatlakozó felületének alapját képez ötlet, elv, elgondolás, eljárás, m ködési módszer vagy matematikai m velet. A m egysége védelmének követelménye, azt fejezi ki, hogy szerz személyhez f z d jogát sérti m vének mindenfajta eltorzítása, megcsonkítása vagy más olyan megváltoztatása vagy megcsorbítása, amely becsületére vagy hírnevére sérelmes lehet. A szerz ség elismerése mellett a m integritásához való jog tekinthet a morális jogok nemzetközileg legszélesebb körben elfogadott alappillérének. Az Szjt 13 §-a a m minden becsület és hírnévsért megváltoztatását személyhez f z d jogsértésnek tekinti, és ennek megállapítását semmilyen más feltételhez nem köti. Az Szjt 94 § (2) bekezdése alapján támasztható kártérítési igény megítélésének egyetlen feltétele, hogy a szerz személyi jogait érint jogsértés ténye fennálljon. Nem tekinthet

jogosulatlannak a többszörözés - akárcsak a fordítás, át-, és feldolgozás, illetve a program egyéb módosítása - amennyiben e felhasználási cselekményeket a (szoftvert legálisan szerz ) felhasználó a program rendeltetésével összhangban végzi, és a felhasználási szerz désben nem kötötték ki az ellenkez jét. A felhasználási szerz désben sem zárható ki, hogy a felhasználó egy ún. biztonsági másolatot készíthessen a szoftverr l, ha az a felhasználáshoz szükséges. Az Európai Unióhoz történ csatlakozás érdekében végzett jogharmonizációs feladatai során a jogalkotó egy, már régóta létez rt töltött ki azzal, hogy az új szerz i jogi törvénybe beiktatta az EU visszafejtésre vonatkozó rendelkezéseit. Visszafejtés (dekompiláció) alatt a kód többszörözését, reprodukálását, megjelenési formájának megváltoztatását, tulajdonképpen a bináris kódból a forráskód visszanyerését értjük. Visszafejtésre a

szerz engedélye nélkül is lehet ség van akkor, ha ez elengedhetetlen az önállóan megalkotott szoftvernek más szoftverekkel való együttes m ködtetéséhez (interoperabilitás) szükséges információ megszerzése érdekében. E m veleteket azonban csak a jogszer felhasználó vagy a szoftver példányának felhasználására jogosult más személy, vagy az megbízottjuk végezheti; ha az interoperabilitás biztosításához szükséges információ nem vált könnyen (más módon) hozzáférhet vé; 5 feltétel továbbá, hogy e felhasználási cselekmények a szoftvernek azokra a részeire (interface) korlátozódjanak, amelyek az együttes m ködtetés biztosításához szükségesek. A megszerzett információ nem használható fel az önállóan megalkotott szoftverrel való együttes m ködtetésen kívüli célra; továbbá mással nem közölhet , kivéve, ha az önállóan megalkotott szoftverrel való együttes m ködtetés ezt szükségessé teszi; és semmi

esetre sem használható fel a kifejezési formájában lényegében hasonló másik szoftver kifejlesztéséhez, el állításához és forgalomba hozatalához, sem pedig a szerz i jog megsértésével járó bármely más cselekményhez. A visszafejtésre vonatkozó szabályokat nem lehet úgy értelmezni, hogy a jogtulajdonos jogait indokolatlanul sértse, vagy a számítógépi program rendeltetésszer használatát akadályozza, és meg kell felelnie a tisztesség (fair use) követelményének. A jogsért személynek polgári és (adott esetben) büntet jogi felel sségét is keletkezteti, azaz nemcsak a szerz -sértettel szemben felel, hanem az állam is élhet a szerz i jogok súlyos megsértése esetén saját büntet jogi felel sségre vonási igényének érvényesítésével. A jogsértéseket - a jogkövetkezmények szempontjából csoportosíthatjuk annak alapján, hogy pusztán a jog megsértéséb l, vagy annak felróható elkövetésér l van-e szó, másrészr l annak

alapján, hogy melyek azok a szerz t megillet jogosultságok, melyeket a konkrét magatartás sért. A szoftverek védelmére vonatkozó hazai szabályozás egyik, s t talán leggyengébb, pontja a büntet jogi szankciók kidolgozatlansága. A szerz , a fejleszt , a jogtulajdonos rendelkezésére álló polgári jogi szankcióknak túlságosan elrettent hatásuk nincsen [10]. Aki nem veszi meg az adott programot, hanem illegálisan másolja és használja, nemcsak azzal okoz hátrányt, hogy nem fizeti meg a normál licence-díjat, hanem a piac további b vítését is akadályozza.[11] A jogsért a normál licencdíjnál alig fizet valamivel többet, feltéve, hogy cselekménye a sértett tudomására jut, és él az Szjt. által biztosított jogi fellépési lehet ségek valamelyikével. Amennyiben a jogsértés ténye homályban marad, még érdemesnek is t nik elkövetni, hiszen – az illegális felhasználók így gondolkodnak –„.ha nem jönnek rá, az tiszta haszon” A

számítástechnika térhódítását követ en kialakult egy új, jövedelmez b nözési forma a szoftverkalózkodás. A szoftverkalózkodás illegális programok terjesztését és felhasználását jelenti. Ez az „iparág” mára világméret problémává vált és a kalózok évente több 100 milliárd dollár veszteséget okoznak a világ szoftver el állítóinak. A szoftverek illegális terjesztése hosszú távon magának a szoftveriparág fejl désének visszatartásához vezet. 2004-ben egy felmérés szerint a Magyarországon üzleti célra használt szoftverek 44%-a volt illegális másolat.[12] Az illegális terjesztés és felhasználás gazdasági problémáit felismerve a szoftvergyártók cégei összefogtak és létrehozták saját szervezeteiket. E szervezetek célja fellépni a szoftverkalózok ellen, a nyilvánosság körében terjeszteni a jogtiszta szoftverek el nyeit, az illetékes hatóságok tudomására hozni az elkövetett jogsértéseket. A Business

Software Alliance (BSA) a legnagyobb amerikai szoftver fejleszt k és terjeszt k nemzetközi szervezete, melynek legf bb célja a jogtiszta számítógépi program felhasználásának el segítése minden olyan országban, ahol a számítástechnika jelent sséggel bír.[13] E célok érdekében küzd a törvénytelen másolatok ellen, el segítve ezzel a törvényes szoftverkereskedelmet. 6 2. Alapismeretek 2.1 Alapfogalmak 2.11 Szoftver licenc típusok Demo Bemutató jelleg programok gy jt neve. A demo program egy nagyobb, kereskedelmi forgalomban megvásárolható program kis részét képezi, mely önmagában is m köd képes. Feladata, hogy ízelít t mutasson a programkörnyezetb l A megvásárlás után egy teljesen új, kib vített programcsomagot kapunk, a shareware programoknál megszokott regisztráció nem végezhet el. Védelmi funkciót nem tartalmaz Free A szabad programok gy jt neve. A program ingyenesen beszerezhet Ez tipikusan az internetr l vagy BBS szerverekr

l való letöltés lehet ségét jelenti, de bármilyen más terjesztési mód is szóba jöhet, például újságok CD-mellékeltén, vagy akár ismer st l, az példányáról való másolat készítésével. Ez a feltétel nem zárja ki azt, hogy a programot ellenérték fejében is terjesszék, azonban nyilvánvaló, hogy az ellenérték fejében a felhasználó egyéb szolgáltatásokat fog elvárni - hiszen ezek nélkül a programot ingyen is beszerezheti. Ilyen egyéb szolgáltatás lehet például a szabad szoftverek összegy jtése és válogatása és ezek együttes terjesztése, részletes dokumentáció összeállítása vagy különleges garancia nyújtása. A program terjeszt jének a terjesztés megkezdéséhez nincs szüksége a program készít jének engedélyére (a szabad terjesztés és módosítás lehet sége miatt az ilyen programoknak több szerz je lehet, így célszer bb inkább fejleszt k közösségér l (community) beszélni), továbbá a terjesztésb l

szerzett nyereségb l nem kötelez a készít nek juttatni. Ett l függetlenül a terjeszt szinte minden esetben támogatja a fejleszt i közösséget, hiszen a további eredményes terjesztéshez azok újabb termékeire van utalva. A terjesztéssel szemben mindössze két megkötés áll fenn: ha a forgalmazó csak a bináris kódot (a futtatható programot) terjeszti, (akár ingyen, akár ellenérték fejében) akkor a forráskódot a felhasználó számára minden esetben, ingyenesen annak rendelkezésére kell bocsátani. Ezen szabályozás nélkül a program (forráskód) megismerhet ségének feltételét könnyen ki lehetne kerülni. - a programmal együtt kell annak dokumentációját is terjeszteni. Freeware Azok a programok, amelyeket szerz jük freeware-ré nyilvánított, minden esetben ingyenesek. Ezek a programok szabadon terjeszthet k, és a felhasználásukra sincsen korlátozás. A szabad szoftverekkel ellentétben azonban a freeware programok forráskódja nem

ismerhet meg, és így a program nem is módosítható. (A freeware programok írói azonban általában nem tiltják a végfelhasználói szerz désben (ha van) a visszafejtést, visszafordítást, mint a kereskedelmi programok írói.) Leggyakrabban a 7 számítógépes munkához kapcsolódó segédprogramok kerülnek ilyen licenctípus alatti megjelenésre. A freeware kategória azonban nem azonos a public domain-nel, hiszen itt a program írója fenntart magának bizonyos szerz i jogokat - a személyéhez f z d jogokat; mindössze a terjesztés és a használat vonatkozásában nyújt szélesebb lehet ségeket a felhasználónak. Az ilyen szoftver kés bbi verzióit alkotója átsorolhatja más kategóriákba; gyakori példa, hogy egy sikeres freeware program következ verziója shareware lesz, majd kés bb kereskedelmi szoftverként jelenik meg. A freeware programokhoz gyakran nem is mellékelik a konkrét licencszerz dést, csak arra utalnak, hogy a programot freeware

kategóriába sorolták. Ebben az esetben a freeware licenc általánosan elfogadott feltételei az irányadóak. Kereskedelmi programok Azok a programok, amelyeket szerz jük abból a célból hozott létre, hogy kereskedelmi forgalomba hozza ket; ezért legfontosabb jellemz je, hogy beszerzésük kizárólag ellenértek fejében lehetséges. A szerz szinte minden esetben hivatásos programozó, vagy program-fejleszt cég, a szoftver pedig egy szoftverterjesztéssel foglalkozó cégen keresztül (ritkább esetben közvetlenül a fejleszt cégt l) jut el a felhasználóig. A kereskedelmi szoftver felhasználására általában nem állnak fenn korlátok, néhány esetben azonban el fordul, hogy a felhasználói jogviszonyt a szerz dés id ben korlátozza. A kereskedelmi program bármilyen terjesztése tiltva van - ennek érdekében a másolatkészítésre is szigorú szabályok vonatkoznak, általában csak a programról való biztonsági másolat készítését engedélyezik (Az

Európai Unió 91/250/ECC irányelve szerint a biztonsági mentés készítését az egyéni licencszerz désben sem lehet megtiltani). A program szerz je nem biztosítja a forráskód megismerhet ségét - hiszen ennek alapján könnyen hasonló képesség szoftvereket fejleszthetne bárki - s t a legtöbb esetben a licencszerz dés a program m ködésének megismerésére vonatkozó minden törekvést (visszafordítás, kódvisszafejtés, bels felépítés elemzése) kifejezetten megtiltja. A program felhasználó általi módosítása szintén nem megengedett Az ilyen licencszerz dés programokra jellemz , hogy a felhasználó jogai pontosan be vannak határolva és a licenc szinte kizárólag a szerz érdekeit védi. A kereskedelmi programokra szinte minden esetben garanciát vállal a terjeszt (habár ez legtöbbször nem terjed ki a szoftver m ködésére, a garanciavállalás csak az adathordozók használhatóságára vonatkozik). A programhoz minden esetben dokumentáció is

tartozik, amely azonban nem mindig papíralapú, a dokumentáció gyakran kizárólag elektronikus formában található meg, amelyet a felhasználó igény szerint kinyomtathat (ez természetesen a szoftver el állítási költségét csökkenti). Public domain Ezek a szoftverek nem állnak szerz i jogi szabályozás (copyright) alatt, szerz jük ugyanis lemondott err l, és a "közösség fennhatósága" (public domain) alá helyezte a programot. Ennek értelmében az ilyen kategóriába sorolt szoftverek esetében a szerz utólag nem változtathat a felhasználási feltételeken; más kategóriába átsorolásra nincs lehet sége. Tehát ilyen programok felhasználására gyakorlatilag semmilyen korlátozás nem áll fenn. 8 Shareware A shareware licenc alatt megjelentetett programok els pillantásra nagyon hasonló feltételekkel rendelkeznek, mint a freeware programok. Ezek is ingyenesen beszerezhet k, és szabadon terjeszthet k. A dönt különbség azonban az,

hogy a shareware programok nem használhatók díjfizetés nélkül korlátlanul és teljeskör en. A díjfizetést, ami a program használatának megkezdése után történik, a program használatának korlátozásával érik el. Erre a legegyszer bb módszer, hogy az ingyenes használatot a licencszerz dés csak bizonyos id re engedi (id korlát), ennek leteltével vagy ki kell fizetni a program árát, vagy fel kell hagyni a használatával. Az id korlát általában a program telepítését l indul, és fix ideig (leggyakrabban 30 napig) tart, de konkrét naptári id ponthoz is köthetik. Ezzel a shareware programok esetében fennáll az a lehet ség, hogy a felhasználó a vételár kifizetése el tt kipróbálja az adott szoftvert, majd a kipróbálási id lejártával döntsön csak arról, hogy megvásárolja-e. Az id korlát mellett más technikai korlátozó eszközökkel is próbálják a felhasználót regisztrálásra késztetni (függetlenül attól, hogy a kipróbálási

id n belül, vagy - jogtalanul - annak lejárta után használja). Ilyenek lehetnek a program késleltetett indítása, az un "bosszantó képerny k" (nag screen), amelyek egy bizonyos ideig a futó program el tt, annak használatát akadályozva hirdetik a regisztráció el nyeit, vagy a program egyes funkcióinak letiltása, amelyek csak a regisztrált verzióban válnak elérhet vé, de az id korlát betartására is gyakran kényszerítik a felhasználót a programba épített id mér vel, amely fizikailag is megakadályozza a jogtalan használatot. Ez bizonyos esetekben azt jelenti, hogy a program shareware verziója a teljes verziós program csak egy töredékét tartalmazza. Trial Id korlátos programok gy jt neve. A trial (kipróbálásra kiadott) szoftver nagyon hasonló az id korlátos shareware programokhoz, ugyanúgy ingyen használható egy bizonyos ideig, indítási számig, vagy adott dátumig, ami után a program már nem indul. A további használat

feltétele a regisztrációs díj kifizetése. Az id korláton belül azonban a program teljes kör en használható, azaz a program összes funkciója kipróbálható. Ezek a programok nem szabadon terjeszthet k, általában a felhasználó más szoftver, vagy hardvertermék megvásárlásával jut hozzájuk. Néhány esetben a regisztráció a shareware programokhoz hasonlóan zajlik, vagy a megvásárlást követ en teljesen új id korlát nélküli programcsomagot kapunk. A védelem ebben az esetben az id korlát, vagy az indítási szám. Ezen szoftver licenceken kívül is találhatók más licenc típusok, s t az egyes típusok keverhet k is egymással és létrehozhatók bel lük új típusok. 2.12 Eszközök és egyéb fogalmak Crack Az informatikai területeken más-más jelentéssel bír, itt azt a bináris állományon elvégzett fizikai módosítás sorozatot értjük, melynek hatására a program viselkedése a védelem szempontjából megváltozik. 9 Debugger Az

egyszer debugger a program forráskódja alapján mutatja a program futását. Realtime debugger használatával a program viselkedését a memóriában tanulmányozhatjuk. Használatát a 24 pontban részletezzük Disassembler Az ilyen programok használatával az indítható bináris állományok bizonyos fokig visszafordíthatók assembly utasítások sorozatára. Használata a 23 pontban kerül ismertetésre. Hexa editor Bináris állományok módosításához használható szerkeszt . Használatát a 25 pontban részletezzük. 2.2 Az assembly nyelv áttekintése Ebben a fejezetben áttekintjük az assembly nyelv alapjait, mivel ennek ismerete nagyban hozzájárul a választott témám problémamentes megértéséhez. Az itt tárgyalt elméleti ismeretek az x86-os architektúrájú számítógépekre vonatkoznak és a Microsoft-féle assembly szintaxist használják fel. A memória legkisebb egysége elérés szempontjából a bájt, ami azt jelenti, hogy a memóriába legkisebb

egységként csak a bájtokat tudjuk írni, illetve olvasni, az egyes biteket csak úgy tudjuk állítani, hogy beírunk a memóriába egy olyan bájtot, aminek a kívánt bitje a megfelel érték . Az egyes memóriabájtokat úgy érhetjük el, hogy minden bájthoz egy cím van hozzárendelve és íráskor vagy olvasáskor ezen cím segítségével hivatkozhatunk rá. A processzor is ezen címek alapján éri el az egyes bájtokat, úgy, hogy egy címbuszon és egy adatbuszon keresztül kapcsolódik a memóriához, ami valójában nem más mint néhány vezeték (8 , 16, vagy 32 db.) és még egy kis elektronika A címbuszon megjelen érték választja ki, hogy melyik memóriabájtot akarjuk elérni és az így kiválasztott bájt az adatbuszon fog mozogni. A gépi kódú nyelv tulajdonképpen számokból áll. Ezek a számok tárolódnak a memóriában és ezeket értelmezi, illetve hajtja végre a processzor. Azonban az utasításokat jelképez összes szám bemagolása egy kicsit

száraz lenne, így kitaláltak egy jelképes nyelvet, melyet úgy alkottak meg, hogy csoportokba szedték az egyes utasításokat, és ezeknek a csoportoknak könnyen tanulható neveket adtak. Ezekb l az utasításokból álló nyelvet nevezték el ASSEMBLY-nek. 2.21 A programozás eszközei Eljárások: ezek olyan programrészek melyek a feladatban többször el forduló, ismétl d folyamatokat takarnak. Ilyenkor ezt csak egyszer írja meg az ember úgy, hogy bárhonnan elérhet , és ha szükséges, megfelel en paraméterezhet legyen. Változók: Egy olyan eszközei a programozásnak, melyek segítségével adatokat tárolhatunk a memóriában. Bizonyos feladatok megoldása elképzelhetetlen lenne változók használata nélkül, mivel a regiszterek száma korlátozott, nem tárolhatunk 10 minden információt ezekben, de mivel a memória mérete nagyságrendekkel nagyobb, ezért kijelölhetünk részeket, ahol a számunkra fontos információt tárolhatjuk. Ciklusok: Ez egyike

a legfontosabb eszközöknek, ugyanis ezek segítségével a feladatban egymás után többször ismétl d m veleteket egyszer síthetünk le. Ha például az a feladat, hogy írjuk ki 10-szer egymás után a nevünket a képerny re, akkor azt meg lehet oldani úgy is, hogy tízszer egymás után megírjuk az adott programot, de úgy is, hogy csak egyszer írjuk meg és egy ciklus segítségével tízszer egymás után lefuttatjuk. Az eredmény ugyanaz, csak a program hossza az utóbbi esetben töredéke a másiknak, emellett egyszer bbé, áttekinthet bbé is válik. Elágazások, feltételek vizsgálata: Talán ez az egyik legegyértelm bb eszköze a programozásnak, ugyanis számtalan olyan eset van, amikor meg kell vizsgálni egy m velet eredményét, egy visszaérkez választ és ennek megfelel en választani kell adott lehet ségek közül. 2.22 A regiszterek m ködése A regiszterek között vannak általános rendeltetés ek, illetve speciálisak. Az általános rendeltetés ek

az EAX, EBX, ECX, EDX neveket viselik egy 32 bites rendszer alatt. Egy ilyen regiszter tulajdonképpen nem más, mint egy 32 bites adat tárolására alkalmas rekesz. Ugyanakkor használhatjuk 16 és 8 bites tárolóként is Ekkor a regiszter nevéb l elhagyva az „E” el tagot, a regiszter alsó 16 bitjére hivatkozhatunk (például: AX), illetve ezt tovább bonthatjuk alsó és fels részre (például: AL,AH). A címtartomány korlátossága miatt a processzor egy id ben a memória csak egy kis részét tudja elérni. Ahhoz, hogy ezt megértsük, legegyszer bb a számítógép memóriáját úgy elképzelni, mint egy nagy könyvet, amib l olvasni, illetve amibe írni szeretnénk. Mivel az egész könyvet egyszerre nem láthatjuk, ki kell nyitnunk azt valamelyik oldalon. Ez az oldal jelképezi azt a szegmenst, amivel egyid ben dolgozni tudunk. A szegmensregiszter határozza meg, hogy melyik memóriarészlettel foglalkozunk (melyik oldalon van nyitva a könyv), az indexregiszter

pedig azt mutatja, hogy a kijelölt részleten belül melyik címen (az oldat melyik sorában) van a szükséges adat. A szegmensregiszterek szerepe egy kivételével meghatározott, ett l eltérni nem célszer : CS Code Segment Kódszegmens DS Data Segment Adatszegmens ES Extra Segment Extraszegmens SS Stack Segment Veremszegmens Az indexregiszterek pedig: SI Source Index Forrásindex DI Destination Index Célindex. Fontos regiszter még a flag regiszter, melynek bitjeit fogjuk vizsgálni. 2.23 Fontosabb utasítások Az x86-os architektúrájú számítógépek általános utasításainak összefoglalását megtalálhatja a Függelékben (11.2 pont) Itt a szempontunkból legfontosabb utasításokról írok néhány mondatot, ami segít a továbbiak megértésében. MOV: A mov utasítás segítségével adatokat mozgathatunk egy forrásból egy célba, például így lehet értéket adni az egyes regisztereknek. A mov utasítást két paraméter követi, el ször a cél majd egy vessz

vel elválasztva a forrás. Ha így egy címkét írunk az adat helyére, akkor a címke szegmenscímét fogja a regiszterbe írni. A mov utasítás segítségével lehet ségünk van egy regiszterbe egy számot, egy másik regiszter értékét, 11 egy címke szegmens illetve offsetcímét vagy egy memóriarekesz tartalmát tölteni vagy fordítva. CMP: Két érték összehasonlítására szolgál. Használata során el ször az az adat áll, amit össze akarunk hasonlítani és utána amivel. A dolog m ködése tulajdonképpen egy kivonáson alapszik, amit a gép csak magában végez el, a regiszterek tartalmát nem változtatja meg. E m velet elvégzése után a flag regiszter egyes bitjei az eredményt l függ en állnak be. A leggyakrabban használt két jelz bit a carry és a zero A carry az úgynevezett átviteli jelz bit értéke 0 ha a második szám nem nagyobb az els nél, azaz ha az els számból kivonnánk a másodikat nem negatív számot kapnánk. Ha az értéke 1,

akkor az eredmény negatív tehát a második szám az összehasonlítás során nagyobb volt. A másik jelz bit a zero, értéke akkor 1, ha a kivonás eredménye nulla lenne, azaz a két szám azonos. Minden más esetben értéke 0 TEST: Egy AND m velet végrehajtása, de a regiszterek értékeit nem változtatja, csak a flaget. JMP: A jmp egy feltétel nélküli vezérlésátadó utasítás. Ha a program ehhez a sorhoz ér, a végrehajtást az utasítás után megadott helyen folytatja. Ez lehet egy címke, de lehet egy regiszter is (si, di, bx) vagy a jmp far utasítás segítségével egy másik szegmensbe is átugorhatunk. JZ: „Jump if Zero” ugró utasítás. A jz csak akkor ugrik a megadott helyre, ha a z bit értéke 1. JNZ: „Jump if Not Zero” ugró utasítás. A jnz csak akkor ugrik a megadott helyre, ha a bit értéke 0. z CALL: Alprogram hívása. Az alprogram végét a RET jelzi Ekkor a program végrehajtás visszakerül a CALL utáni sorra. 2.3 Disassembler m

ködésének bemutatása Az assembly kód megírása után a fordító egy gépi kódú bináris állományt állít el . Azt hihetnénk, hogy ennek a bináris állománynak a tartalma csak a processzor számára érthet , pedig mi magunk is betekintést nyerhetünk a tartalmába. Tudnunk kell, hogy az operációs rendszer az indítható exe állományok esetében az indítási rész beolvasása után, a fájl egy részét (vagy kis fájl esetén az egészet) a memóriába tölti, majd az ott lév utasításokat sorban végrehajtja. Ezek az utasítások a fájlban is és a memóriában is ugyanúgy hexadecimális számokkal vannak ábrázolva. Minden egyes utasításhoz tartozik egy hexadecimális szám és utána az esetleges paraméterek. Ha tudjuk, hogy melyik hexadecimális számhoz melyik assembly utasítás tartozik, és ennek az utasításnak milyen paraméterei lehetnek, akkor ebb l ki tudnánk olvasni a teljes utasítást. Természetesen azért ez a gyakorlatban egy kicsit

komplikáltabb, hisz például egy jmp (EBh) utasítás után nem az új cím áll, hanem az, hogy mennyit kell ugorni, hogy a következ utasítást kapja a program, tehát egy EB05 hexadecimális bejegyzés azt jelenti, hogy a jelenlegi címet (ez nem a jmp utasítás címe, hanem az utolsó paraméteré) figyelembe véve 5 bájt kihagyása után folytassa a program a végrehajtást. Néhány fontos utasítás hexadecimális kódja: 12 jmp = EBh jnz = 75h jz = 74h cmp = 83h nop = 90h Azért, hogy ne kelljen az összes mnemonic kódját és paraméterezését betanulni, úgynevezett disassembler programot használhatunk. 1. ábra: Disassembler m ködés közben A vizsgált fájl megnyitása után megkezd dik a teljes kör elemzés. A program feltérképezi az ugrás és szöveg referenciákat, majd ezt az aktuális kódnál meg is jeleníti így szolgáltatva b vebb információt a f bb utasításokhoz. A program három oszlopot jelenít meg, melyek jelentése a következ . Az

els oszlop szemlélteti az utasítás lehetséges elhelyezkedését a memóriában, a második oszlop jelenti az utasítás és a paraméterek kódját hexadecimális számokkal ábrázolva, a harmadik oszlop pedig magát az assembly utasítást mutatja. Bár már ez is sok információt közöl a program futásáról, de elemzéshez a real-time debuggerek fogják szolgáltatni a legtöbb adatot. Mindenesetre a programmal való közelebbi ismerkedést célszer itt kezdeni. Két fontos információt tudhatunk meg az elemzés során. Az els , hogy milyen küls importált függvényekkel dolgozik a program. Ezt nagyon fontos tudni, ugyanis ennek ismeretében már könny dolgunk lesz a real-time debuggerrel „betörni” a programba. A másik fontos információ a szöveg konstansok kiírásának helye Ennek az információnak a tudatában a hivatkozás körüli rész nagyobb figyelmet igényel, s t már ilyenkor is sok minden felderíthet róla. Egy „Incorrect registration code!”

mondat nem csak a program felhasználója felé küldött hibajelzés, hanem számunkra konkrétan kijelöli azt a programrészt, ahol a hiba kijelzésre kerül. Ezután nem kell mást tenni csak megkeresni visszafelé azt az elágazást, ahonnan a program futása erre az ágra került, és ott egy módosítást alkalmazni, vagy felderíteni az ott végrehajtott algoritmust és az alapján sorozatszám generátort írni. Természetesen az utóbbi sokkal nagyobb szakértelmet, id t és kihívást jelent. 13 2.4 Debugger m ködésének bemutatása Ha valaki már foglalkozott programfejlesztéssel, az már valószín leg találkozott a debugger fogalmával. A debugger egy olyan eszköz, mellyel a programozó akár lépésenként elemezheti a program m ködését így derítve fényt az esetleges hibákra. A programnyelvekhez tarozó fejleszt i környezetek általában tartalmaznak valamilyen debuggert, mellyel az eredeti forráskódon keresztül láthatjuk a tényleges futást.

Legfontosabb dolog, amit be tudunk állítani a rengeteg hasznos dolog közül, a megszakítás (breakpoint). Ezt egy adott utasításra kell elhelyezni, ahol szeretnénk, hogy a program futása megszakadjon. Ez a megszakítás lehet feltételhez kötött is Az egyes utasításokon több módszerrel is mozoghatunk (nyomkövetés). Az egyik a belépés (step into), ami a tulajdonképpeni lépésenkénti elemzést jelenti, így az egyes eljáráshívásnál magába az eljárásba is belelépünk. Ha ezt nem szeretnénk megtenni, akkor használhatjuk az átlépés (step over) funkciót, mely átlép a hívott eljáráson, és nem merül bele a „részletekbe”. Hasznos funkció még a figyel ablak (watch window), melybe felvehetjük a minket érdekl változókat, és megtekinthetjük az aktuális értéküket. 2. ábra: Turbo Pascal nyomkövetés közben A legtöbb szoftverhez azonban nem mellékelnek forráskódot a szerz k, de így is lehet ségünk van megfigyelni a program m

ködését. Ehhez egy olyan debuggerre van szükség, ami nemcsak egy adott programot vizsgál, hanem rendszerszinten lehet vele megfigyelni akár az operációs rendszer m ködését is. Ilyen például a Windowshoz adott debug nev program, aminek kezelése azonban nem egyszer . Éppen ezért sok más vizuálisan jobban megjelenít debuggert tölthetünk le az internetr l. Egy régebbi fajtájúra láthatunk példát a 3. ábra ábrán 14 3. ábra: A Turbo Debugger Mindegyikre jellemz , hogy a program utasításait assembly nyelven írja le, valamint lekérdezhetjük a regiszterek tartalmát és feltérképezhetjük a memóriát. Az információszerzésen kívül interaktívan beleavatkozhatunk a program futásába, illetve lehet ségünk van minden adat (beleértve a regisztereket is) értékének megváltoztatására. Az ilyen változtatásokkal azonban óvatosan kell bánni, mert könnyen el idézhetünk egy végtelen ciklust, vagy egy rendszerösszeomlást. Természetesen

itt is használhatunk töréspontokat. Egy ismeretlen programban viszont csak akkor tudunk elhelyezni töréspontot, ha tudunk valami konkrét utasításra hivatkozni. Ezt meg tudjuk tenni, mert a programok általában az MS Windows API függvényeit (lásd Melléklet 11.1) használják fel a m ködésük közben, melyekre állíthatunk figyelést. A töréspont bekövetkeztekor már könnyen vizsgálhatjuk a futó programot a lépésenkénti elemzés valamelyikével. 2.5 Hexa editor m ködésének bemutatása Hexa editort tucatszám tölthetünk le a webr l, az alapvet k akár ingyenes programok is lehetnek, a bonyolultabb tudásúak fizet sek. A bemutatás szempontjából számunkra a legegyszer bb editor is jó, mert a kijelölt feladatot maximálisan megoldja. Nyilvánvaló, hogy egy ilyen egyszer bb program megírása egy programozónak sem jelenthet komoly kihívást. A hexa editor feladata hasonló a text editor feladatához, de annál egy kicsit b vebb. Itt nem szöveget

szerkesztünk, hanem bináris állományokban bájtokat Egy bájton 256 különböz jelet tudunk eltárolni, ezeknek az értékei a hexa editorban rendre 00h és FFh (0-255) közé kell, hogy essenek. 15 4. ábra: Hexa editor Egy egyszer szerkeszt három f részb l áll. A baloldalon található a címtartomány, ami mutatja, hogy hol járunk a fájlban. Ez úgy épül fel, hogy mindig az adott sor els oszlopának a címét mutatja, természetesen hexadecimális számrendszerben. A középs rész egy összefügg 16 oszlopos sor, aminek az értékei a fájl egyes bájtjainak értéke hexadecimális számrendszerben ábrázolva. Az egyes bájtok címét úgy tudjuk kiszámolni, hogy a sor el tt álló címhez hozzáadjuk az adott oszlop sorszámát hexadecimálisan, mégpedig úgy, hogy az els oszlop sorszámát 0-nak tekintjük. Így az adott címhez 0h-Fh-ig (0-15) terjed értéket adhatjuk A jobb oldali oszlopban az egyes bájtok ASCII megjelenítését láthatjuk, ami segít

azonosítani például a szövegeket. Ebben az oszlopban is szerkeszthetjük a bájtokat, de itt nem a hexadecimális kódokat kell megadni, hanem egyszer en leütni a megfelel karaktert. A szerkeszt további fontos tulajdonsága a hexadecimális kódra való keresés. Ez a feladatunk szempontjából majd a végén lesz fontos, amikor már tudjuk, hogy mit kell megváltoztatni a fájlban, csak azt nem tudjuk, hogy hol. Ha már meg van a kódrész, könnyen megállapíthatjuk a címét, így más programból tudunk rá hivatkozni. 16 3. Védelmi és megkerülési módszerek 3.1 Általános védelmi módszerek 3.11 Jelszó A legegyszer bb védelmi forma a jelszó (password, pass code) kérése. Ilyenkor a program a teljes m ködéshez, vagy akár már az induláshoz is egy olyan kódsorozatot kér, amit megadva és leellen rizve a felhasználót jogosultsághoz juttatja. Ez a kód tulajdonképpen bármi lehet, elvileg sehonnan sem tudható meg. A begépelés után egy alprogram

leellen rzi valamilyen rutin alapján a kódot, és ha helyesnek találja, akkor valahova bejegyzi, hogy megtörtént a regisztráció. Innent l kezdve a program már nem kéri a jelszót. 3.12 Sorozatszám A sorozatszám (serial number) talán a legtöbbet alkalmazott védelmi módszer. A program regisztrációjához meg kell adnunk a nevünket, esetleg címünket, illetve egyéb más személyes adatokat. Az adatok megadása után meg kell adnunk a kapott sorozatszámot. Ezt a számot a program regisztrációs díjának kifizetése után levélben, e-mailben, vagy a program vásárlásakor a szoftverrel együtt kapjuk. Helyesen megadva ezeket az adatokat, a program m ködése teljes kör vé válik, használata semmilyen körülmények között nem akadályozott. Megszokott, hogy a regisztráció a program f menü sorában a Help Register menüpontból indítható, de ett l eltér is lehet a folyamat, részletesen többet a program dokumentációjából tudhatunk meg. 3.13 Kulcsfájl

Ha a programban nem lehet megadni sorozatszámot, de létezik más mód a regisztrációra, akkor ez a legtöbb esetben egy kulcsfájl (key file). A kulcsfájl a szoftver kifizetése után szintén e-mailben, vagy lemezen elektronikus formában kerülhet a jogos tulajdonoshoz. Legtöbbször ez egy bináris állomány, aminek a kiterjesztése „key” Ez az állomány tartalmazza a regisztrált felhasználó adatait és egy ellen rz összeg (check sum) információt, aminek az olvasásakor a program el tudja dönteni, hogy ténylegesen egy érvényes kulcsfájlról van szó. Ezt a fájlt a telepített program mappájába kell másolni, ha mást nem mond a felhasználói útmutató. Innent l kezdve a programot korlátozások nélkül használhatjuk. 3.14 Id korlát Sokszor találkozhatunk olyan programmal, melynek felhasználói licenc szerz désében adott, hogy a program mennyi ideig használható. Ez az id tartam teljesen egyedi lehet, például 14 vagy 30 nap. A program telepítése

után az adott id elteltével a szoftver többször nem indítható, ilyenkor egy tájékoztató szöveget jelenít meg a program, hogy hol tudjuk beszerezni a teljes verziót. Ugyanígy ebbe a témakörbe sorolható, hogy nem az id t, hanem az indítások számát korlátozzák. Látni fogjuk, hogy ez a védelem gyakorlatilag ugyanolyan módszerekkel kerülhet meg, mint az id korlát. A program indításakor a Help About menüpontban találhatunk általában arra utalást, hogy meddig m köd képes a használt szoftver. 17 3.15 Hardverkulcs A hardverkulcs egy olyan áramkör, amely egyedi azonosításra alkalmas. Ez azt jelenti, hogy minden ilyen áramkörnek kódszáma van, és minden kódszám a gyártó által garantáltan csak egyszer fordul el . A kulcsot a program indítása el tt kell a számítógép valamely portjára csatlakoztatni. A program az indításkor és futás közben rendszeresen ellen rzi a hardverkulcs meglétét, hiánya esetén hibaüzenetet küld. A

hardverkulcs lehet vé teszi, hogy a felhasználó a szoftvert más-más számítógépen is használja, de egyidej leg csak egy helyen. 3.2 Általános védelmi módszerek kikerülése A következ részekben a védelmi módszerek lehetséges megkerülését vizsgáljuk meg. Ez a leírás úgy vizsgálja a problémát, ahogy egy átlagos felhasználó próbálkozhatna. A felvetett ötletek nem jelentenek garanciát arra, hogy azok egyes konkrét programokon alkalmazva ténylegesen is m köd képesek. Az alábbi módszerek leírása nem zárja ki azt, hogy csak ezek használhatók és csak így. 3.21 Ini fájlok A régebbi windowsos programok az összes beállításaikat a hozzájuk tartozó úgynevezett ini fájlokban tárolják. Ide kerülhet többek között az az információ is, mely megmutatja a program telepítésének idejét, az indítások számát, valamint ide kerül bejegyzésre a regisztráció megtörténte is. Ez a nagyon egyszer esetekben egy registration=1 bejegyzés,

de többnyire bekerül a regisztrációs folyamatkor megadott név és a hozzá tartozó helyes sorozatszám. Természetesen, ha nincs meg a helyes sorozatszámunk, akkor itt sem írhatjuk be önkényesen, mivel a program az induláskor általában ellen rzi a beírt sorozatszám helyességét. Ugyanakkor néhány esetben jól jöhet az ini fájllal való trükközés. Ha a nagyon egyszer esetet nézzük, akkor lehet próbálkozni a registration=0 bejegyzés 1-re való állításával, de ebben az esetben számolnunk kell esetleg azzal, hogy a program keresni, s t ellen rizni fogja a sorozatszámot. A legjobb akkor próbálkozni, ha a programunk id korlátos. Ekkor a telepítés dátumát átírva újra m köd képessé tehetjük a lejárt programot. Ugyanígy kijátszhatjuk azt is, hogy többször indítsuk el a programot, mint ahányszor ez esetleg engedélyezett. Ez az információ szintén az ini fájlba kerül bejegyzésre, ha szerencsénk van, akkor számunkra is érthet rész

lesz az, például started=5, de az is lehet, hogy számunkra semmitmondó bejegyzés tartalmazza az indítások számát. Ha tanácstalanok vagyunk, akkor próbálkozhatunk azzal, hogy elmentjük az eredeti ini fájlt, majd csak ezután indítjuk el a programot. Ekkor a program kiolvassa a fájlból az indítások számát, megnöveli 1-el és visszaírja azt az ini fájlba, és nem mellékesen leellen rzi, hogy elértük-e már a maximális indítások számát. Bizonyos esetekben azt tapasztalhatjuk, hogy az új ini fájl és a régi ini fájl között egyetlen bejegyzés fog eltérni, és ez nem más, mint az indítások száma. Ekkor máris találtunk egy kerül utat, mégpedig azt, hogy mindig lenullázzuk ezt a bejegyzést, miel tt elérné a maximumot. Lehetséges azonban, hogy ez az információ kódolva kerül a fájlba (például: started=&@xd). Ekkor nyilvánvalóan nem tudjuk lenullázni az értékét, de ha id ben másolatot készítünk az ini fájlról még az

elején egy-két indítás után, akkor kiküszöböljük azt, hogy ha az indítások száma eléri a maximumot, ne tudjuk elindítani. Ekkor próbálkozhatnánk azzal, hogy visszamásoljuk a mentett állományt az eredetit felülírva, így egyszersmind azt a látszatot keltve a programnak, hogy még mindig csak egy-kétszer indítottuk el. 18 Ha az id korlátos bejegyzést nem találjuk, vagy annak tartalma kódolt formátumban van tárolva, akkor szóba jöhet még a program újratelepítése. Ne feledjük azonban, hogy egy egyszer újratelepítés nem oldja meg a problémát, mert az ini fájl nem fog felülíródni. A program eltávolítása során, pedig sok esetben ott marad a telepítési könyvtárban, és ha megint oda telepítjük a programot, akkor ugyancsak nem mentünk semmire a telepítéssel. Tehát az eltávolítás után, de még a telepítés el tt meg kell gy z dnünk arról, hogy a telepítési mappából az ini fájl el legyen távolítva. Ez után már

telepíthetjük a programot, sok esetben újra használható lesz. Lehet azonban, hogy a program ini fájlja nem a telepítési könyvtárban van, hanem a Windows könyvtárában, így célszer ott is körbenézni, ha azt tapasztaljuk, hogy a program még mindig nem indul. Ésszer nek t nhet, hogy a program lejárta után egyszer en töröljük az ini fájlt, azzal a feltételezéssel, hogy ha a program nem tudja kiolvasni a telepítési dátumot, netalán az indítások számát, akkor újra generálja az ini fájl általános beállításait, és úgy veszi, hogy most telepítették. Azonban a legtöbb esetben ez nem vezet eredményre, ugyanis a programok a szükséges fájl hiánya miatt hibaüzenettel leállnak, és újratelepítésre kérik a felhasználót. 3.22 Registry hack A 32 bites Windows operációs rendszerek megjelenése után a szoftverek beállításai átköltöztek a regisztrációs adatbázisba, az ini fájlok ideje lejárt. Tulajdonképp innent l kezdve a

beállítások még jobban rejtve maradnak a felhasználó el l. A programok számára publikus függvényekkel elérhet az adatbázis, így könnyen kezelhet vé válik az adathalmaz. Minden program összes beállítása egy helyre kerül, így megel zhet az ini fájlok szétszóródása és nehézkes karbantartása. Ugyanakkor az operációs rendszer lehet séget biztosít az adatbázis megnézésére, s t szerkesztésére is. Mivel ebben az adatbázisban vannak tárolva az operációs rendszer saját beállításai is, ezért sok szakember óvatosságra int a használatakor. 5. ábra: A regisztrációs adatbázis felépítése A regisztrációs adatbázis szerkeszt meghívása a regedit.exe program indításával történik. Baloldalon egy fát látunk, ahol hat f kategóriába vannak sorolva a beállítások. Ha az egyes pontokat kinyitogatjuk a + jelre kattintva, akkor láthatóvá válnak az alkategóriák. Ezt egészen addig nyitogathatjuk tovább, amíg már nincs tovább mit

kinyitni. Ekkor a minket érdekl mappára kattintva a jobb oldalon megjelennek a benne tárolt beállítások nevei és azok értékei. A programok beállításai a [HKEY CURRENT USERSOFTWARE] és a [HKEY LOCAL MACHINESOFTWARE] ágon találhatók általában a program neve, vagy 19 írójának cégneve mappában (lásd 5. ábrát) A beállítások tulajdonképp ugyanazok, melyeket esetleg már az ini fájlokban is megszokhattunk. Ide ment dhetnek azok az adatok is, melyek a korlátozásra vonatkoznak, mint az installáció id pontja, indítások száma stb. Mivel tulajdonképpen a tárolási módszereken kívül semmi nem változott, így az ini fájloknál bemutatott módszereket meg lehet próbálni itt is. Regisztrációs ág lementésével és kés bbi visszatöltésével ugyanazt érjük el, mint az ini fájloknál a fájl visszamásolásakor. Elmondhatjuk azt is, hogy a program eltávolításakor ezek a bejegyzések nem törl dnek, így a program újratelepítésekor ugyanazt

az állapotot kapjuk, mint amikor letöröltük a programot. A lejárt programok így továbbra sem indulnak el, ha újra akarjuk használni ket, akkor a bejegyzéseket mindenképp törölni kell. Érdekesség azonban, hogy az ini fájlok törlésével ellentétben a regisztrációs adatbázisból való törlés után a legtöbb program elindul, és újra generálják az alap értékeket. Csak nagyon összetett program esetében kell újratelepíteni a programot 3.23 Dátum visszaállítás Id korlátos programoknál (sajnos) nagyon sok esetben beválik a dátum visszaállítása. Ez azért lehetséges, mert a programok csak a telepítési dátumot mentik el az indításkor lekérdezett aktuális dátumot nem. Mivel az ellen rzés sokszor az aktuális dátum és a telepítési dátum alapján történik a következ képlet szerint ha (mai dátum-telepítési dátum<maxnap) akkor program indítható:=igaz; különben program indítható:=hamis; az aktuális dátum a

maxnap+telepítési dátum alatti értékre való állításával a program mindig indíthatóvá válik. Bár a dátum állítgatása körülményesnek t nhet, a legtöbb felhasználónak megéri ez a kis kellemetlenség azért, hogy tovább használják a lejárt programot, f leg ha figyelembe vesszük, hogy a dátumvizsgálat legtöbbször csak az indításkor fut le. Nyilvánvaló lépés lenne a programozók fel l, hogy az indításkor aktuális dátumot is el kellene menteni. Ekkor a dátum visszaállítás kisz rhet lenne, és hibaüzenettel lekezelhet vé válna. Én ilyen megvalósítást csak nagyon kevés program esetében tapasztaltam. Persze ez a védelmi módszer is kijátszható, hisz ha indítás el tt mindig ugyanazt a dátumot állítjuk be, akkor a program azt hiszi, hogy mindig ugyanaznap lett futtatva (ha a dátummal együtt az id t is lementi, akkor ez egy kicsit már kényelmetlenebbé válik), és nem észleli a dátum visszaállítást. Mégis ez az ellen rzés

számomra elég szimpatikus, mert egy átlag felhasználó általában csak akkor gondol a dátum visszaállítására, amikor már észreveszi, hogy lejárt a program. Ebben az esetben viszont a dátum visszaállítása már nem vezethet eredményre, más módszerekhez kell folyamodnia. 3.24 Sorozatszám generátor A sorozatszám generátorok (serial generator) az átlagembereknek íródnak. Az ilyen programok használata nem legális, ugyanakkor nagyon is célravezet azok számára, akik ingyen akarják a teljes programot használni. Használatukkal könnyen regisztrálhatóvá válnak azok a programok, melyeket az ilyen megoldások védenek. Általában minden felkapott program valamennyi verziójához megtalálhatók ilyen generátorok f leg az interneten [14]. A program tulajdonképp el állítja a felhasználó számára a megfelel kódot, melyet a használni kívánt szoftver kér. Ily módon a megrendelés és a regisztráció költsége nem terheli t. 20 6. ábra: A Nero

program egyik sorozatszám generátora 3.25 Kulcsgenerátor A kulcsgenerátor (key generator) m ködése teljesen hasonló a sorozatszám generátorhoz. Az egyetlen különbség, hogy a megadott adatok alapján nem egy kódot számol ki, hanem legyártja a szoftver teljes m ködéséhez szükséges bináris fájlt, és azt elhelyezi a megfelel helyre. Ez általában a szoftver installációs könyvtára Jellemz en az internetr l már csak a kész kulcsfájlokat tölthetjük le, melyet már csak a telepítési könyvtárba kell másolni (ekkor persze nem a saját adataink lesznek a fájlban). 3.26 Crack A crack vagy patch programok az eredeti szoftver bináris kódját változtatják meg, úgy módosítva azt, hogy a szoftver összes tiltott funkciója használható legyen, valamint a szoftverre ne vonatkozzanak egyéb korlátozások [15]. A crack fájl használata során meg kell adni a szoftver adott fájljának az elérési útvonalát, és ha minden jól megy, akkor megtörténnek

a módosítások. A jól megírt crack használata után, bár a program esetleg továbbra is sharewarenek vagy trialnak gondolja magát, a program ekvivalensé válik a teljes verziójú szoftverrel. Ilyen programok általában csak adott verziószámmal ellátott szoftverekhez használhatók, mert kés bb a hely, ahol a módosításokat kell elvégezni az újabb verzióban, fizikailag megváltozik. Az olyan crack programokat, amik a változást is figyelembe veszik univerzális cracknek nevezzük. 7. ábra: Példa egy crack programra 21 4. A shareware programok Ebben a fejezetben a shareware védelmet fogjuk megvizsgálni. A védelem ismertetése mellett nagy hangsúlyt fektettem arra, hogy elemezzük azokat a részeket, ahol a védelem támadható. A támadásra itt csak ötleteket vetek fel, ami nem garantálja, hogy az összes ilyen védelmet használó program esetében használhatónak bizonyulnak, illetve nem zárja ki, hogy másféle támadási pont ne lenne. Ezek az

ötletek viszont már egy szakértelemmel rendelkez programozó gondolatait tükrözik. 4.1 Shareware programok felépítése Azt, hogy a telepíteni kívánt programot milyen védelemmel látták el, csak a telepítés után tudhatjuk meg. Amennyiben a programot shareware licenccel látták el, akkor a következ védelmekre számíthatunk: jelszó, sorozatszám, kulcsfájl (lásd 3.11- 313 pontok). Ha megnézzük a súgó menüpontban, hogy van-e Registration vagy hasonló menüpont, akkor jelszavas vagy sorozatszámos védelemr l van szó. Ekkor egy 8 ábraábrához hasonló ablakot láthatunk. 8. ábra: Az Irfanview program regisztrációs ablaka A felhasználó nevét, esetleg cégnevet, és a kódot megadva a program leellen rzi a kapott kódot, és értesítést küld (lásd 9. ábra és 10 ábra) Ez a tény számunkra kés bb nagyon fontos lesz. 22 9. ábra: Sikertelen regisztráció 10. ábra: Sikeres regisztráció Egy másik lehetséges védelemmel állunk szemben

(lásd kulcsfájl 3.13 pont), ha nem találunk olyan menüpontot, ahol regisztrálni lehet. Ekkor a program súgójából informálódhatunk. A következ regisztrációs utasítás a WinRar nev program súgójából származik [16]: „Registration procedure: Upon receipt of your registration fee with the completed registration form you will receive a registration key file which will correspond to the registration string given in the registration form. Upon receipt of your registration key file you should put it to the WinRAR folder. If the key is archived, in a .RAR file, please extract the key from the archive in order to register your copy of WinRAR It is possible, depending upon the facilities available at your local registration site, to have the key delivered to you by e-mail or by your local postal service on diskette.” „Regisztrációs eljárás: A kitöltött regisztrációs lap és a regisztrációs díj ellenében egy regisztrációs kulcsfájlt kap, melyben a

regisztrációs lapon megadott információk szerepelnek. A regisztrációs kulcs kézhezvétele után azt a WinRAR mappába kell másolni. Ha a kulcsfájl tömörített, akkor kérjük kitömöríteni a WinRAR sikeres regisztrációja érdekében. Mód van arra, a területi képviselett l függ en, hogy a kulcsot e-mailben, vagy postai úton keresztül floppy lemezen kapja meg.” 4.2 Shareware programok védelme Els ként nézzük végig, hogy miként m ködik belülr l a shareware programok védelme általában. Ezt a következ C programnyelven írt kódrészlet eljárások fogják szemléltetni: int Check Serial(char *name, char serial) { int magic1=Generate Magic1(name); /* valahogy el állítunk egy/ /* számot a névb l és / int magic2=Generate Magic2(serial); /* a sorozatszámból is / if (magic1==magic2){ return 1; } /* ha egyezés van,akkor a / /* regisztráció sikeres / else { return 0; } } 23 void Check Registration() { registered=0; /* ez egy globális változó,

amit minden / /* eljárásból el lehet érni / openRegistry(); /* Itt az esetleges regisztrációs adatok kerülnek kiolvasásra / /* / /* char rname : az adatbázisban talált Felhasználói név / /* char rserial : az adatbázisban talált Sorozatszám / /* int found : Igaz, ha a regisztrációs adatbázisban / /* megtalálhatók a szükséges információk */ closeRegistry(); if (found) { int b=Check Serial(rname,rserial); if (b) { registered=1; } } } void RegButtonClick() /* ez az eljárás fog lefutni,ha a regisztráció menüpontját válasszuk/ /* char uname : A begépelt felhasználói név / /* char userial: A begépelt sorozatszám / { int b=Check Serial(uname,userial); if (b) { /* kiírjuk a regisztráció sikerét / openSuccessWindow(); /* bejegyezzük a registrybe / writeDataToRegistry(uname,userial); /* beállítjuk a regisztrált program tulajdonságot / registered=1; /* ezt valamikor kihagyják és inkább / /*újraindítják a program teljes futását / } else {

openFailureWindow(); /*kiírjuk,hogy hibás a beírt infó / } } public void main() { Check Registration(); /* program indítása / /* formok, classok ect létrehozása / /* Ha nem regisztrált akkor letiltunk néhány funkciót / if (!registered) { setProperties to unregistered(); } /* / exit(0); } Amennyiben a program védelme, csak jelszóra (lásd 3.11 pont) korlátozódik, akkor a beírt név nem fog szerepet játszani a Check Serial eljárásban. Ilyenkor a magic1 értéke fixen rögzített a programban. Az hogy a jelszó ellen rzése hogyan történik, tulajdonképpen csak a programozó fantáziája szabja meg. A legegyszer bb ellen rzési módszer a direkt összevetés. Ekkor a programban el re megadott jelszóval (magic1) egyez nek kell lennie a beírt kódnak (ekkor a Generate Magic2 függvény egy identikus leképezés lesz). Ennek a módszernek egy apró finomítása, hogy több jelszót tárolunk a fájlunkban, és ezek valamelyikével kell megegyeznie a beírt kódnak.

A probléma ezekkel az eljárásokkal az, hogy a sztring konstans az exe fájlban is látszik, így abból könny szerrel kiolvasható. Egy jobb módszer az, ha a beírt kódból egy hasító függvénnyel (ezt valósítja meg a Generate Magic2 függvény) legyártunk egy értéket, és azt hasonlítjuk össze a programban. Ilyen lehet például az, hogy a karakterek ASCII kódjait összeadjuk és 24 valamilyen modulóját vesszük. Ekkor a jelszó nincs eltárolva a programban, csak az, hogy minek kellene megfelelnie a kódnak (magic1). Így a helyes kódok száma elég sok lehet, de egy jól megválasztott hasító eljárással meg lehet akadályozni, hogy véletlenszer en beírt kód elfogadásra kerüljön. A valós életben ilyen védelemmel látták el például a Nero Burning Rom cd író programot is [17]. Sok esetben viszont a helyes sorozatszám (lásd 3.12 pont) függ a beírt felhasználói információktól. Ez az eljárás tulajdonképpen abban segít, hogy

mindenkinek egyedi kódot tudjunk kiosztani, ezzel együtt csökkentjük az esélyét, hogy egy találomra beírt kód elfogadásra kerüljön. A védelem ekkor már a programkódban szemléltetett két hasító függvénnyel fog dolgozni, melynek egyike a névb l állít el egy számot, a másik a sorozatszámot dolgozza fel. Ha mindkét eljárás eredménye megegyezik, akkor a regisztráció elfogadásra kerülhet, és jelezzük a felhasználó felé, hogy a m velet sikeres volt. Amennyiben a két érték nem egyezik, akkor figyelmeztetjük a felhasználót, hogy a beírt információ pontatlan vagy hibás. A regisztráció megtörténtét a program általában ini fájlba, vagy a Windows regisztrációs állományába rejti. Az ini fájl általában az indított fájllal megegyez könyvtárban helyezkedik el, és a regisztrációs bejegyzés mellett a program más beállításait is tartalmazhatja. A Windows regisztrációs adatbázisában a [HKEY CURRENT USERSoftwareprogaramneve],

illetve a [HKEY LOCAL MACHINESOFTWAREprogramneve] kulcs alatt lehet megtalálni az adott programra vonatkozó beállításokat, így a regisztrációs bejegyzéseket is (lásd 3.22 pont 5. ábra) Fontos tudni, hogy a programok indításkor nem csak azt ellen rzik, hogy regisztrálva lettek-e, hanem a megadott kódot is leellen rzi, mint ahogyan azt a példán láttuk. Így a bejegyzések esetleges törlésekor, vagy módosításakor a már regisztrált software visszavált regisztrálatlanná. A shareware program használhat más regisztrációs eljárást is, mint például azt, hogy a teljes m ködéshez kulcsfájlt kér. Ebbe a kulcsfájlba tárolhatjuk el a felhasználói információkat speciálisan kódolva, visszaolvasáskor ezt az információt kell visszafejteni egy algoritmussal. Ha az algoritmus hibátlanul végig tud futni, akkor a kulcsfájl helyes és a programot regisztráltnak lehet tekinteni, ha nem, akkor küldhetünk hibajelzést („Keyfile corrupted!”), vagy

tekinthetjük úgy, hogy nincs is meg a szükséges fájl. Az utóbbi két esetben a program továbbra is korlátozásokkal indul csak el. 4.3 Shareware programok védelmének megkerülése Most, hogy már ismerjük a shareware programok védelmét, elgondolkozhatunk azon, hogy milyen pontokon lehet ezeket az eljárásokat támadni. Azt már tudjuk, hogy a regisztrálatlan programok támadhatók az internetr l letölthet sorozatszám generátorokkal, kulcsgenerátorokkal, vagy speciális crack programokkal. De hogyan állíthatók el az ilyen programok? A kérdésre a következ pontok fognak választ adni, melyek azonban nem arra keresnek választ, hogy hogyan kell, hanem arra, hogy hogyan lehet megkerülni a védelmet. 4.31 Sorozatszám generátorok írása A sorozatszámos védelemmel ellátott programok gyakorlatilag tálcán kínálják a letiltott funkciók engedélyezését. Ha tudjuk a sorozatszámot és esetleg a hozzá tartozó nevet (ha ez szükséges), akkor a program

automatikusan felold minden korlátozást. Ez azért jó, mert nem kell minden egyes funkciót körüljárni és feltörni, csak a helyes sorozatszámot kell megtudni. Közelítsük meg a problémát elméleti síkon, felhasználva a 4.2 pontban szerepl szemléltet példaprogram eljárásokat. Tehát adott a név, mivel ezt mindenki maga 25 választhatja meg, de nem ismerjük a hozzá tartozó sorozatszámot. A névb l a Generate Magic1 eljárás egy magic1 kódot hoz létre. Ennek a kódnak az értékének egyeznie kell azzal a kódnak az értékével, amit a Generate Magic2 eljárás állít el a számunkra szükséges sorozatszámból. Tehát a Generate Magic1 eljárás lépéseit mindenképp ismernünk kell, és szükségünk van a Generate Magic2 eljárás lépéseire is, de ebben az esetben fordított végrehajtással és inverz m veletekkel. Azaz a sorozatszám megkapható a Generate Magic2-1(Generate Magic1(név)) végrehajtásával, ahol a Generate Magic2-1() az eredeti

függvény lépéseinek visszafelé való végrehajtását jelenti inverz m veletekkel. Megjegyezzük, hogy ha a program nem használja fel a nevet a regisztrációhoz (azaz jelszavas védelemr l van szó), akkor az összehasonlításkor kiolvasott magic1 kódra kell végrehajtani a Generate Magic2-1() függvényt. Elméletben most már gond nélkül meg tudnánk írni sorozatszám generátorunkat, de amíg nem tudjuk milyen lépéseket takarnak a függvények, addig erre a gyakorlatban kevés esélyünk van. A következ kben azt elemezzük, hogyan lehet hozzáférni a kérdéses függvényekhez az eredeti programban. Ehhez be kell „törnünk” a programba, mégpedig úgy, hogy minél közelebb legyünk a Check Serial() eljáráshoz. Tudjuk viszont, hogy ez az eljárás akkor fog csak lefutni, miután beírtuk az adatokat és megnyomtuk az OK gombot. Az, hogy a programba való behatolás hogyan történik, nem írható le általánosan, de az elmondható, hogy az adatbevitelhez a

programok a Windows API (lásd Melléklet 11.1) könyvtárát használják Célszer el ször egy disassembler programmal próbálkozni, mely megmondja, hogy milyen küls függvényeket használ a program. Ami nekünk szükséges az általában a getdlgitemtexta Windows API függvény, de lehet próbálkozni a hmemcpy függvénnyel is (Win98 alatt). Ha sikerül bejutnunk a programba, akkor ott tartunk, hogy a dialógus ablakba beírt adatok átkerülnek a program adat memória területére. Ezt le tudjuk olvasni a függvény paraméteréb l, vagy ha kell, rákereshetünk a program memóriaterületén a kérdéses adatra. Ezután már csak azt kell tennünk, hogy a kérdéses memóriacímre (például, ahol a nevet tárolja a program) kérünk egy figyelést. Ha az adott memóriaterületen olvasás történik, akkor szakadjon meg a program futása (breakpoint). Ha ez is megtörténik, akkor elértük célunkat, hisz pont ott vagyunk a kódban, ahol elkezd dik a név feldolgozása. Ezt a

kódrészletet kielemezve megírható a Generate Magic1() eljárás. A következ kben a sorozatszámra kell ugyanezt végignézni, majd a kapott eljárást visszafelé inverz m veletekkel megírni. Így megkaptuk a Generate Magic2-1() függvényt is 4.32 Kulcsfájl elkészítése Tudjuk, hogy a kulcsfájllal védett program az indításkor megkeresi és megnyitja a hozzá tartozó fájlt, és ha ez sikerül, akkor végigelemzi a benne lév adatokat. Ha az elemzés sikeres, akkor a program regisztrált, különben pedig nem. A védelem megkerülését itt is egy megszakítás beállításával kezdjük a debuggerben. A megszakítás pont a fájl megnyitását fogja figyelni a createfilea Windows API függvény használatával. Ha ez bekövetkezik, akkor figyelemmel követhetjük az ellen rz algoritmust. Megtudhatjuk, hogy mi a kulcsfájl neve, ha esetleg ez a dokumentációból nem derült volna ki. Ezután létrehozhatjuk a fájlt néhány karakterrel feltöltve. Ha most folytatjuk az

elemzést, akkor kiderül, hogy a fájlnak milyen tulajdonságokkal kell rendelkeznie. Innent l kezdve csak azt kell figyelnünk, hogy mit kíván az algoritmus ahhoz, hogy sikeresen végigfusson. Ha kész, akkor készen vagyunk a fájllal. Mivel most már tisztában vagyunk a szükséges fájl felépítésével, meg is írhatjuk a generátorunkat. 26 4.33 Crack program írása A crack program az eredeti program viselkedését változtatja meg. Ezt a viselkedést úgy érdemes megváltoztatni, hogy minél kevesebb változtatásra kerüljön sor maximális hatékonyság mellett. Nézzük végig a példaprogramunkat elemezve, hogy hol érdemes változtatásokat eszközölni. Az els szóba jöv megoldás a sok közül az, ha a f program részéb l eltávolítjuk a Check Registration eljárást, majd az ellen rz feltételt is. public void main() { Check Registration(); /* program indítása / /* formok, classok stb létrehozása / /* Ha nem regisztrált akkor letiltunk néhány

funkciót / if (!registered) { setProperties to unregistered(); } /* / exit(0); } Így elérhetjük, hogy ne történjen meg az ellen rzés, és ne tiltódjanak le az egyes funkciók. Ennek az eljárásnak több hátránya van, ami arra késztet minket, hogy ne használjuk. Az egyik legf bb hátulüt , hogy a program más területén is el fordulhatnak ellen rzések, így nem tudjuk garantálni az összes tiltott funkció feloldását. A másik nehéz kérdés, hogy ezeket a kódrészeket hogyan találjuk meg, mivel semmi támpontunk nincsen ahhoz, hogy hol is kell keresni ezeket az utasításokat a memóriában. Persze el lehetne indulni akár a program elejér l is, de mivel az ellen rzés el tt a program számtalan dolgot végezhet még, ezért az elemzés igen id igényessé és bonyolulttá válik. Az utolsó ellenérv pedig az, hogy egy eljáráshívást nem „szép” dolog törölni, mivel azt a program részletet ki kell töltenünk valamivel, arról nem is beszélve, hogy

a függvény hívhat más függvényeket is, ami esetleg nekünk is kell, és ha ez nem lesz meghívva, akkor az nekünk sem jó. Ha nem törölhetjük a Check Registration eljárást, akkor próbáljuk tovább bontani az ott lév utasításokra, hogy elérjük célunkat. void Check Registration() { registered=0; /* ez egy globális változó, amit minden / /* eljárásból el lehet érni / openRegistry(); /* Itt az esetleges regisztrációs adatok kerülnek kiolvasásra / /* / /* char rname : az adatbázisban talált Felhasználói név / /* char rserial : az adatbázisban talált Sorozatszám / /* int found : Igaz, ha a regisztrációs adatbázisban / /* megtalálhatók a szükséges információk */ closeRegistry(); if (found) { int b=Check Serial(rname,rserial); if (b) { registered=1; } } } 27 Láthatjuk, hogy a regisztrált tulajdonsághoz két darab ellen rzésen kell keresztülesnünk. Az els dolog az, hogy a regisztrációs adatbázisban szerepeljenek a szükséges

bejegyzések. Ezt els körben, bár nem szép dolog, megoldhatjuk a regisztrációs adatbázis szerkeszt segítségével. A probléma az, hogy mik legyenek a bejegyzések, de ezt az elemzés során kideríthetjük. Természetesen ez is id veszteségbe kerül. Választhatnánk azt is, hogy a kódot úgy módosítjuk, hogy mindenképp az els ellen rzés igaz ága hajtódjon végre, de mindjárt látjuk is, hogy ez nem lesz jó, mert a Check Serial függvény nem létez paramétereket kap, és a program kifagyhat. Folytatásként már csak a második ellen rzést kell úgy módosítani, hogy mindig az igaz ág kerüljön végrehajtásra, azaz a registered=1 utasítás. Ez az eljárás sorozat már jobb megközelítése a problémának, mint az el z volt. A kódot könnyen tudnánk azonosítani a regisztrációs adatbázis nyitásának figyelésével, elemezhetjük a szükséges bejegyzéseket, és megváltozathatjuk az utolsó ellen rzést. A legnagyobb probléma azonban az, hogy ehhez a

felhasználó segítségét kell kérnünk, hogy vigye be a regisztrációs adatbázisba a szükséges kulcsokat. Nyilvánvaló, hogy ezt nem várhatjuk el t le, ezért ezt a megoldást is el kell vetnünk. Most már világos, hogy a program biztonságos futásához be kell írnunk a regisztrációs adatbázisba a szükséges kulcsokat. Mivel ezt nem bízhatjuk a felhasználóra, ezért magát a programot kell felhasználnunk arra, hogy ezt megtegye helyette. Ha figyelmesen megnézzük a példaprogramot, észrevesszük, hogy a RegButtonClick eljárás pont ezt teszi. void RegButtonClick() /* ez az eljárás fog lefutni,ha a regisztráció menüpontját válasszuk/ /* char uname : A begépelt felhasználói név / /* char userial: A begépelt sorozatszám / { int b=Check Serial(uname,userial); if (b) { /* kiírjuk a regisztráció sikerét / openSuccessWindow(); /* bejegyezzük a registrybe / writeDataToRegistry(uname,userial); /* beállítjuk a regisztrált program tulajdonságot /

registered=1; /* ezt valamikor kihagyják és inkább / /*újraindítják a program teljes futását / } else { openFailureWindow(); /*kiírjuk,hogy hibás a beírt infó / } } Látjuk viszont azt is, hogy a regisztrációs bejegyzés csak akkor fog megtörténni, ha a leellen rzött felhasználói név és a hozzá tartozó sorozatszám helyes. Mivel ezt most nem tudjuk garantálni, ezért módosítsuk a feltételt úgy, hogy mindig az igaz ág kerüljön végrehajtásra. Ekkor azt értük el, hogy a felhasználó bármilyen nevet és kódot megadhat. Az OK gomb lenyomása után, bár az ellen rzés nem biztos, hogy sikeres, mégis megjelenik a sikeres regisztráció ablak, majd kiíródik az adatbázisba a szükséges információ, legtöbb esetben aktiválódnak a letiltott elemek. Sikerünknek akár joggal örülhetnénk is, hisz kis er feszítéssel nagy dolgokat értünk el, de több probléma is felmerül a következ kben. Az els észrevehet dolog, hogy a program következ

indításakor nem lesz regisztrált. Ez érthet is, hiszen erre van kitalálva a Check Registration eljárás. Tehát nincs más hátra, mint mégiscsak megkeresni ezt a programkód részletet is a memóriában és megváltoztatni a második feltételt. A m ködés így már teljesnek mondható, hisz a szükséges regisztrációs bejegyzés egyszer módon beíródik az adatbázisba, ezt induláskor a program kiolvassa, 28 leellen rzi, de az eredményt l függetlenül beállítja a regisztrált program tulajdonságot igazra. A másik probléma viszont, hogy nem biztos az, hogy a „regisztráció sikeres” ablak megjelenítése és a regisztrációs kulcsok kiírása ugyanabban a feltételvizsgálatban van. Azaz megtörténhet, hogy a program kiírja ugyan a regisztráció sikerét, de mást nem tesz, mert a következ feltétel vizsgálatot már nem kerestük meg, és nem módosítottuk. Megállapítható, hogy ezen eljárássorozat használható, m köd képes, de nagyon id

igényes. Azonban, ha más módszer nem alkalmazható, akkor feltétlen érdemes ezzel próbálkozni. A fenti próbálkozásokon látszott, hogy nem elég hatékonyak. Vagy nem m ködtek biztonságosan, vagy túl sok id t kellett ráfordítani az elemzésre. Van viszont még egy függvényünk, amit érdemes megvizsgálni. A Check Serial függvény magát a tényleges ellen rzést valósítja meg, így természetes, hogy érdekl désünk középpontjában áll. int Check Serial(char *name, char serial) { int magic1=Generate Magic1(name); /* valahogy el állítunk egy/ /* számot a névb l és / int magic2=Generate Magic2(serial); /* a sorozatszámból is / if (magic1==magic2){ return 1; } /* ha egyezés van,akkor a / /* regisztráció sikeres / else { return 0; } } Ahhoz, hogy a regisztráció sikeres legyen a függvénynek 1-el kell visszatérnie. Ezt úgy tudnánk garantálni, ha a megfelel nevet és kódot írjuk be, de mivel ezt nem tudjuk, egyszer en módosítsuk a feltételt

úgy, hogy mindig az igaz ág hajtódjon végre. Ezt a programrészt ugyanúgy találjuk meg, mint ahogy a sorozatszám generátornál (lásd 4.31 pont) próbálkoztunk. Gondoljuk végig, hogy ezzel a kis változtatással mennyi mindent értünk el, ugyanis a programban már sehol sem kell módosítanunk. A regisztráció sikeres lesz, a regisztrációs kulcsok kiírásra kerülnek még akkor is, ha nem egy feltételben vizsgálják véletlenül, valamint a program indításakor sem kell semmit tennünk, hisz akkor is ez a függvény vizsgálja az adatokat. Azaz megállapíthatjuk, hogy a legkevesebb változtatással a legnagyobb eredményt értük el rövid id alatt. Most, hogy már tudjuk hogyan találjuk meg módszeresen azt a helyet, amit módosítanunk kell, nézzük meg mit is értünk konkrétan módosítás alatt. Nézzük például, hogy hogyan mutat a Check Serial eljárás assembly nyelven: Check Serial: lea push call lea push call mov cmp jnz mov jmp rosszag: xor vege: ret

eax,dword ptr[NAME] ; eax ; Generate Magic1 ; eax,dword ptr[SERIAL] ; eax ; Generate Magic2 ; ebx,dword ptr[magic1] ; ebx,dword ptr[magic2] ; rosszag ; eax,1 vege eax,eax név címét átadjuk paraméterben magic1 függvénynek a serial címét átadjuk paramlterben a magic2 függvénynek a magic1 érték összevetése a kapott magic2 értékkel ha nem egyezik ugrás 29 A memóriában ez körülbelül így jelenhet meg1 : lea push call lea push call mov cmp jnz mov jmp xor ret eax,dword eax 21A324 eax,dword eax 21C231 ebx,dword ebx,dword 012321 eax,1 012423 eax,eax ptr[esi-4] ptr[esi+10] ptr[D42123] ptr[D42A45] A debugger vagy a disassembler segítségével kiolvasható, hogy az ugró utasítás kódja a memóriában a 7506 hexa számmal2 van ábrázolva. A program kódját úgy kell alakítanunk, hogy mindig az igaz ág kerüljön végrehajtásra. Ez most itt háromféleképpen is elvégezhet . Az egyik egyszer megoldás, ha az utasítást üres utasításra (nop)

cseréljük. Vegyük azonban észre, hogy míg a jnz utasítás 2 bájtot foglal a memóriában, addig a nop csak 1 bájtot használ. Éppen ezért a teljes elágazás két nop utasítással tüntethet el. Ez azt jelenti, hogy a 7506 hexadecimális adatot le kell cserélnünk 9090 hexa adatra. A következ lehetséges megoldás, hogy a jnz utasítást inverz utasításra (jz) cseréljük. Ezt azért tehetjük meg, mert kevés esélye van annak, hogy a kód beírásakor az illet hibátlan kódot adjon meg. Ekkor elérjük, hogy a hibás ág csak akkor fusson le, ha jó adatot adtunk meg, így csak hibás adatokkal végezhetjük el a regisztrációt. Ehhez a kódban az eredeti 7406 hexa adat helyett a 7506 értéket kell írnunk. Ez a megoldás tulajdonképpen a legjobb, mert ez jár a legkevesebb változtatással. A harmadik lehetséges megoldás az, ha a jnz rosszag utasítást átírjuk jmp joag feltétel nélküli ugrásra. Ezt megtehetjük az utasítás és a memóriacím

módosításával, azaz 7406 hexa adat helyett a EB00 értéket kell beírnunk. A memóriában való módosítás azonban még nem elég ahhoz, hogy a program végleg „feltört” legyen. Az eszközölt módosításokat magában a fájlban is el kell végezni. Ehhez szükségünk lesz a módosítás körüli (utasítás el tti és utáni) parancsok hexadecimális kódjára is. A kapott eredményt, mint keresési mintát használjuk a hexa editor keres jében, miután megnyitottuk vele az indítható állományt. Figyeljünk arra, hogy a kapott eredmény nem biztos, hogy számunkra megfelel . El fordulhat, hogy ugyanaz a minta többször is szerepel a fájlban. Ilyen esetben még több kódra van szükségünk a mintához, hogy 100%-ra be tudjuk határolni a számunkra fontos helyet. Ha ez megvan, akkor ki tudjuk olvasni, hogy mely fizikai címen kell változtatni a fájlban. Ennek ismeretében, és a megváltoztatni kívánt régi és új hexa értékekkel meg tudjuk írni a crack

fájlunkat is. Ha univerzális cracket akarunk írni, akkor felhasználva a már megtalált keresési mintát, egy keresést is be kell építeni a programunkba. 1 2 A memóriacímek találomra lettek felírva A szám vége csak egy körülbelüli érték 30 4.4 A Mirc 616 program védelmének részletes elemzése Az elméleti ismeretek leírása után szeretnék a gyakorlatban is bemutatni egy shareware programon alkalmazott védelmet. Itt els sorban a sorozatszám generálásával fogunk foglalkozni, mivel ez jelenti a nehezebb részt. A bárhol alkalmazható crack eljárást a kés bbiekben egy másik programon fogom szemléltetni a Trialware programok fejezetben. Az itt leírt módszerek csak és kizárólag a bemutatás célját szolgálják tanulmányi céllal. A program letölthet a http://wwwmirccom (20050531) oldalról 4.41 Ismerkedés a program védelmével A program indításakor egy figyelmeztet ablakot (lásd 11. ábra) is látunk, felhívva a figyelmet arra, hogy a

szoftver shareware és 30 napon belül regisztrálni kell. A programban egyébként semmi nincs letiltva, gyakorlatilag ez a figyelemfelkeltés van csak beleépítve. A 30 nap letelte után a program továbbra is használható marad, csak a szöveg változik arra, hogy letelt a 30 nap próbaid . 11. ábra: A Mirc program indításkor A regisztrációt (lásd 12. ábra) a Help Register menüpontból érhetjük el, ahol a nevünket és egy regisztrációs számot kell megadnunk, melyet a vásárlás után kapunk meg. A regisztráció után az indításkor nem jön el a figyelemfelkelt ablak, illetve a Help About menüpontban megjelen ablakban láthatjuk, hogy kinek a nevére van regisztrálva a program. 31 12. ábra: A Mirc regisztrációs ablaka 4.42 Stratégiák a védelem megkerülésére A program valószín leg eltárolja az installációs dátumot valahová, hogy tudja, hány napunk van még vissza. Ha megvizsgáljuk a regisztrációs adatbázist, akkor meg is találjuk a

[HKEY CURRENT USERSOFTWAREMIRC] útvonalon egy Lastrun bejegyzést, ami egyértelm en valami dátumot azonosít. El reállítva a dátumot láthatjuk, hogy ennek a kulcsnak az értéke nem változik. A kulcs törlése után azt látjuk, hogy a program elölr l kezdi a számlálást. Ha élünk azzal a lehet séggel, hogy az installációs dátum elé állítjuk vissza a dátumot, akkor látni fogjuk, hogy a bejegyzés értéke változik, és onnan lesz számítva az eltelt napok száma. A dátum állításával ebben az esetben nem sokra megyünk, hisz a program nem jár le, csak figyelmezet, hogy regisztrálni kéne. Számunkra az lenne jó, hogy a program elindításakor a figyelmezet ablak nem jönne el . Ezt crack-el el tudnánk tüntetni, de mivel más programokban nem csak ilyen korlátozások vannak, ezért ott nem lenne kényelmes minden egyes védelmet kiiktatni. Azonban ezeknél a programoknál meg van a lehet ségünk arra, hogy teljes verzióvá tegyük ket. Ehhez

ismernünk kell a névb l sorozatszámot el állító algoritmust, vagy crack alkalmazásával a visszatérési értéket hamisítani. A következ pontban az el bbir l lesz szó, ami jóval több ismeretet igényel, mint annak a helynek a megtalálása, ahol a cracket alkalmazni kell. Így ha megismerjük közelebbr l az algoritmust, az olvasó meg tudja állapítani, hogy hol alkalmazna esetleg cracket, ha nem kívánja megírni a sorozatszám generátort. 4.43 Kódelemzés A program kódjába akkor akarunk betörni, miután beírtuk a nevünket és a sorozatszámot. Ehhez a SendDlgItemMessageA Windows API függvényre való figyelést kell beállítanunk a debuggerben. Az OK gomb lenyomása után a következ kódrészletet láthatjuk: * Reference To: USER32.SendDlgItemMessageA, Ord:0236h | :004C7BA4 8B3DB4365800 mov edi, dword ptr [005836B4] :004C7BAA 68E0075A00 push 005A07E0 ;ide jön a név :004C7BAF 68E7030000 push 000003E7 :004C7BB4 6A0D push 0000000D :004C7BB6 6883000000 push

00000083 :004C7BBB 56 push esi :004C7BBC FFD7 call edi ;beolvasás :004C7BBE 68C80B5A00 push 005A0BC8 ;ide jön a serial :004C7BC3 68E7030000 push 000003E7 :004C7BC8 6A0D push 0000000D 32 :004C7BCA :004C7BCF :004C7BD0 :004C7BD2 :004C7BD7 :004C7BDC :004C7BE1 :004C7BE3 :004C7BE9 :004C7BF0 6884000000 56 FFD7 BAC80B5A00 B9E0075A00 E81FFAFFFF 85C0 0F84E5000000 C6053A085A0000 33C0 push 00000084 push esi call edi ;beolvasás mov edx, 005A0BC8 ;serial mov ecx, 005A07E0 ;név call 004C7600 ;??? test eax, eax jz 004C7CCE ;ugrás ha hiba mov byte ptr [005A083A], 00 xor eax, eax Láthatjuk, hogy a beolvasó függvényhívás többek közt egy memória címet is paraméterként kap, ahova kés bb a név és a sorozatszám kerül. Ezután ezeket az adatokat átadja a program egy függvénynek. Mivel mi most végig szeretnénk járni az adatok útját, ezért térképezzük fel, hogy mit tesz a hívott eljárás. * Referenced by a CALL at Addresses: , :004C7A48 , :004C7BDC |:004C7789 |

:004C7600 81EC08020000 sub esp, 00000208 :004C7606 56 push esi :004C7607 57 push edi :004C7608 8BF2 mov esi, edx ;serial :004C760A 8BF9 mov edi, ecx ;név :004C760C BA04010000 mov edx, 00000104 ;260 bájt :004C7611 8D4C2408 lea ecx, dword ptr [esp+08] :004C7615 E81679F5FF call 0041EF30 ;terület kinullázása :004C761A BA04010000 mov edx, 00000104 ;260 bájt :004C761F 8D8C240C010000 lea ecx, dword ptr [esp+0000010C] :004C7626 E80579F5FF call 0041EF30 ;terület kinullázása :004C762B 57 push edi ;név :004C762C BA04010000 mov edx, 00000104 :004C7631 8D4C240C lea ecx, dword ptr [esp+0C] :004C7635 E80678F5FF call 0041EE40 ;másolása :004C763A 56 push esi ;serial :004C763B :004C7640 :004C7647 :004C764C :004C7653 :004C7657 :004C765C :004C765E :004C7660 :004C7661 :004C7666 :004C7667 :004C766D BA04010000 8D8C2410010000 E8F477F5FF 8D94240C010000 8D4C2408 E8A4FDFFFF 85C0 740E 5F B801000000 5E 81C408020000 C3 mov edx, 00000104 lea ecx, dword ptr [esp+00000110] call 0041EE40 ;másolása lea

edx, dword ptr [esp+0000010C] lea ecx, dword ptr [esp+08] call 004C7400 ; tényleges vizsgálat test eax, eax jz 004C766E ; hiba esetén ugrik pop edi mov eax, 00000001 pop esi add esp, 00000208 ret Amit ebben a kódrészben láthatunk, hogy a program két területet kiürít a memóriában, majd odamásolja a megadott nevet és a sorozatszámot. Ezután hív egy eljárást megadva paraméterként az új helyeket. Látni fogjuk, hogy ez a hívás fogja ténylegesen elvégezni a teljes vizsgálatot. Minden, ami eddig történt ennek az el készítése volt Lássuk mit is takar pontosan ez a vizsgálat. * Referenced by a CALL at Addresses: , :004C76C7 |:004C7657 | :004C7400 - 004C750A 33 Ezek az utasítások bájtonként írnak a memória egy bizonyos területére, mely a következ mátrixot adják ki (ezt kés bb a program a számolások során konstans táblaként fogja használni): 0B 0C 10 0E 06 0B 0A 10 0A 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 06 0E 0A 0E 0E 09 08 08 0C 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 05 0B 04 0E 0C 0A 04 10 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 0C 06 0B 04 0B 0A 06 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Az ezutáni utasítások a nevet vizsgálják: :004C7515 :004C7518 :004C751A :004C751B :004C751D :004C751F :004C7521 :004C7523 8D7001 8A10 40 84D2 75F9 2BC6 3BC1 730D lea esi, dword ptr [eax+01] ;név kezd címe+1 mov dl, byte ptr [eax] ; aktuális karakter inc eax ; a végén a név utáni helyre mutat! test dl, dl ; vége van már? jne 004C7518 ; következ karakter sub eax, esi ; hossz kiszámítása cmp eax, ecx ; ecx=4 jnb 004C7532 ; ha kisebb kilép (eax=0 lesz) Azt láthatjuk, hogy a tábla felépítése után a program megvizsgálja, hogy legalább 4 karakter hosszú-e a beírt név. Ha

nem, akkor hibát jelez, úgy hogy eax-ot nullázza Nézzük mi történik, ha megfelel hosszúságú a beírt név. :004C7532 :004C7536 :004C7538 :004C7539 :004C753E :004C7540 :004C7543 :004C7545 8B5C2410 6A2D 53 E8228D0A00 8BF0 83C408 85F6 74DE mov ebx, dword ptr [esp+10] push 0000002D ;’-’ push ebx ;serial call 00570260 ;’-’ keresése mov esi, eax add esp, 00000008 test esi, esi ;’-’ helye je 004C7525 ;rossz formátum esetén ugrás A hívott eljárás megnézi, hogy a sorozatszámunk tartalmaz-e ’-’ jelet. Visszatér értékként azt a helyet kapjuk ahol el ször talált ’-’ jelet. Ha ez 0, akkor ez azt jelenti, hogy a beírt sorozatszám nem tartalmaz ’-’ jelet, azaz rossz. :004C7547 53 :004C7548 C60600 :004C754B E8F38F0A00 push ebx ;serial címe mov byte ptr [esi], 00 ;0-za a ’-’ jelet call 00570543 ;??? Ez a rész kinullázza a talált ’-’ jelet, majd a sorozatszám címét átadva meghív egy függvényt, ezzel egyszersmind két sztringre

bontotta a sorozatszámot. Nézzük meg mit számol a program a sorozatszám els felével. :00570588 :0057058B :0057058C :0057058F :00570591 :00570593 0FB60E 46 83F92D 8BD1 7405 83F92B movzx ecx, byte ptr [esi] ;aktuális karakter inc esi ;mutass a következ re cmp ecx, 0000002D ;’-’ mov edx, ecx ;el jel elmentése je 00570598 cmp ecx, 0000002B ;’+’ 34 :00570596 7504 jne 0057059C ;egyik sem * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00570591(C) | :00570598 0FB60E movzx ecx, byte ptr [esi] ;ha ’+’ v ’-’ akkor :0057059B 46 inc esi ;következ karakter Megvizsgálja, hogy a megadott szám el jeles-e. Ha igen és negatív, akkor elmenti az el jelet edx-be, majd a következ karaktert olvassa. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00570596(C) | :0057059C 33C0 xor eax, eax ; szumma nullázása * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:005705BF(U) | :0057059E 83F930 cmp ecx,

00000030 ; ’0’ :005705A1 7C0A jl 005705AD :005705A3 83F939 cmp ecx, 00000039 ; ’9’ :005705A6 7F05 jg 005705AD :005705A8 83E930 sub ecx, 00000030 ; így megkapja a karakter :005705AB EB03 jmp 005705B0 ; tényleges értékét * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:005705A1(C), :005705A6(C) | :005705AD 83C9FF or ecx, FFFFFFFF ;vége Ha a karakter 0 és 9 között van, akkor azt átalakítja tényleges számmá, egyébként jelzi, hogy hiba lépett fel és azt már nem kell figyelembe venni. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:005705AB(U) | :005705B0 83F9FF cmp ecx, FFFFFFFF ; vége van? :005705B3 740C je 005705C1 :005705B5 8D0480 lea eax, dword ptr [eax+4*eax] :005705B8 8D0441 lea eax, dword ptr [ecx+2*eax] :005705BB 0FB60E movzx ecx, byte ptr [esi] :005705BE 46 inc esi :005705BF EBDD jmp 0057059E ;’0’-’9’ vizsgálat újra Ha még nincs vége, akkor megszorozza a szummát 4-el és hozzáadja az eddigi

összeghez, majd ezt az összeget szorozza 2-vel, és ehhez adja hozzá a vizsgált számot. Nagyon érdekes lehet, hogy az aritmetikai m veletek leegyszer sítése miatt a program a lea utasítást használja a számoláshoz. Nézzük meg figyelmesen, mit is akar ez a számolás jelenteni. Jelöljük a szummát a-val és a beolvasott számot c-vel Ekkor a következ utasítást lehet felírni: a:=(a+4*a)2+c. A zárójel felbontása után a következ t kapjuk: a:=10a+c. Ez azt jelenti, hogy a szumma nem más lesz, mint az adott szám 10-es számrendszerben felírva! * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:005705B3(C) | :005705C1 83FA2D cmp edx, 0000002D ;’-’ volt a szám :005705C4 5F pop edi :005705C5 5E pop esi :005705C6 7502 jne 005705CA 35 :005705C8 F7D8 neg eax ; negatív összeg * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:005705C6(C) | :005705CA C3 ret Az eljárás a végén megnézi, hogy negatív volt-e a szám.

Ebben az esetben a negatív szummát adja vissza eredménynek. Az algoritmust látva kijelenthetjük, hogy ez az eljárás az ismert StringToInteger függvény feladatát látja el. Nézzük tovább, mit tesz a program a sorozatszámmal, miután az visszatért a konvertálás hívásából: :004C7550 :004C7553 :004C7556 :004C7557 :004C7559 :004C755C :004C755E :004C755F :004C7564 :004C7566 :004C7569 :004C756D 83C404 C6062D 46 8BE8 803E00 74C7 56 E8DF8F0A00 8BCF 83C404 89442410 8D5101 add esp, 00000004 mov byte ptr [esi], 2D ;’-’ vissza inc esi ; következ char mov ebp, eax ; fél serial # cmp byte ptr [esi], 00 ; ’-’ után nincs je 004C7525 ; semmi ugrás push esi ; 2. fél serial ch call 00570543 ; StrToInt mov ecx, edi ; név címe add esp, 00000004 mov dword ptr [esp+10], eax ; 2. fél serial # lea edx, dword ptr [ecx+01] ; név cím+1 A ’-’ jelet visszateszi a program a helyére, majd a maradék sorozatszámra hívja meg az el bb megismert StringToInteger függvényt.

Az eredményt most nem a regiszterek egyikében tárolja, hanem kiteszi a memóriába (esp+10)! Ecx regiszterbe betölti a név címét, edx-be pedig egyel nagyobbat. Feltehetjük, hogy most jön a név vizsgálata * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C7575(C) | :004C7570 8A01 mov al, byte ptr [ecx] ; név aktuális karaktere :004C7572 41 inc ecx ; következ char :004C7573 84C0 test al, al ; van benne valami? :004C7575 75F9 jne 004C7570 ; ha nincs =>a végén vagyunk :004C7577 2BCA sub ecx, edx ; hossz kiszámítása :004C7579 BE03000000 mov esi, 00000003 ; számláló lesz!!! :004C757E 33D2 xor edx, edx ; ez is!!! :004C7580 33DB xor ebx, ebx ; szumma nullázása :004C7582 3BCE cmp ecx, esi ; hossz<=3 ? :004C7584 7E22 jle 004C75A8 ; ha igen =>hiba :004C7586 EB08 jmp 004C7590 Ez az utasítás sorozat megint leellen rzi a név hosszát, ami azért érdekes, mert ezt már egyszer megtette, így úgy néz ki, hogy ez látszólag teljesen

felesleges kód. Megint csak azt kapjuk, hogy ha nincs beírva legalább 4 karakter, akkor ez hibát ad. * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:004C7586(U), :004C75A6(C) | :004C7590 0FB6043E movzx eax, byte ptr [esi+edi]; akt char kód ; esi 3-ról indul! :004C7594 0FAF449414 imul eax, dword ptr [esp+4*edx+14] ; esp+14 ; címen a táblázat van :004C7599 03D8 add ebx, eax ; szumma :004C759B 42 inc edx ; táblázat számláló növelése :004C759C 83FA26 cmp edx, 00000026 ;ha nagyobb mint 38 36 :004C759F 7E02 :004C75A1 33D2 jle 004C75A3 xor edx, edx ;akkor nullázzuk * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C759F(C) | :004C75A3 46 inc esi ; következ karakter :004C75A4 3BF1 cmp esi, ecx ; esi<hossz? :004C75A6 7CE8 jl 004C7590 ; olvasd a következ t Ebben a részben azt látjuk, hogy a név 4. karakterét l kezdve el állít egy szumma összeget a konstans tábla értékeinek segítségével. A képlet így

írható le: i:=3; j:=0; ciklus sum:=sum+ord(NEV[i])*TABLA[j4]; i:=i+1; j:=j+1; ha j>38 akkor j:=0; amíg i<hossz; A ciklus addig fut, amíg a név hossza tart. Itt használta ki az el z kódrész eredményét (név hossza) a program. Biztosítva azt, hogy a konstans táblán ne fusson túl véletlenül az algoritmus, 39 lépésenként lenullázza a megfelel számlálót. Az ord függvény az aktuális karakter karaktertáblabeli értékét adja (ordinal value). * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C7584(C) | :004C75A8 3BEB cmp ebp, ebx ; ebp= fél serial # ; ebx= névb l generált szám :004C75AA 0F8575FFFFFF jne 004C7525 ; hiba Itt történik a leglényegesebb ellen rzések egyike. A program összehasonlítja a sorozatszám elejéb l kiszámolt adatot, a névb l kapott adattal. Ha nincs egyezés, akkor hibát jelez! :004C75B0 :004C75B5 :004C75B7 :004C75B9 :004C75BB :004C75BD BE03000000 33D2 33DB 3BCE 7E23 8D4900 mov xor xor cmp jle lea

esi, 00000003 edx, edx ; számláló 0-zása ebx, ebx ; itt lesz az összeg ecx, esi ; hossz<=3? 004C75E0 ecx, dword ptr [ecx+00] * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C75DE(C) | :004C75C0 0FB6443EFF movzx eax, byte ptr [esi+edi-01]; akt char-1 :004C75C5 0FB62C3E movzx ebp, byte ptr [esi+edi] ; akt char :004C75C9 0FAFC5 imul eax, ebp :004C75CC 0FAF449414 imul eax, dword ptr [esp+4*edx+14] ; esp+14 a tábla címe :004C75D1 03D8 add ebx, eax ; szumma :004C75D3 42 inc edx ; tábla számláló növelése :004C75D4 83FA26 cmp edx, 00000026 ; ha nem nagyobb mint 38 :004C75D7 7E02 jle 004C75DB ; akkor állj a kövre :004C75D9 33D2 xor edx, edx ; különben nullázzuk * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C75D7(C) 37 | :004C75DB 46 :004C75DC 3BF1 :004C75DE 7CE0 inc esi cmp esi, ecx jl 004C75C0 ; vége? ; olvasd a következ t Ebben a kódrészben a program egy újabb szummát állít el . Ehhez újból a nevet

használja, mégpedig úgy, hogy újból megvizsgálja, hogy 3-nál hosszabb-e. Ha nem, akkor a negyedik karaktert l kezdve összeszorozza az aktuális karaktert, és az az el tt álló karakter kódját, majd ezt megszorozza egy a konstans táblából származó kóddal. Ezt képlettel a következ képpen írhatjuk fel: i:=3; j:=0;sum:=0; ciklus sum:=sum+ord(NEV[i-1])*ord(NEV[i])TABLA[4j]; i:=i+1; j:=j+1; ha j>38 akkor j:=0; amíg i<hossz; A ciklus futása a név hosszáig tart. A képlet tulajdonképpen azzal több, hogy a szorzatba az aktuális karakter el tti kód is beleszámít. Itt is figyel arra az algoritmus, hogy a konstans táblán ne fusson túl. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C75BB(C) | :004C75E0 8B4C2410 mov ecx, dword ptr [esp+10] ;2. fel serial # :004C75E4 5F pop edi :004C75E5 5E pop esi :004C75E6 33C0 xor eax, eax :004C75E8 3BCB cmp ecx, ebx ; ugyanaz amit most számoltunk? :004C75EA 5D pop ebp :004C75EB 0F94C0 sete al ;

egyezés esetén al=1 :004C75EE 5B pop ebx :004C75EF 81C4A4000000 add esp, 000000A4 :004C75F5 C3 ret Az eljárás végén visszaolvassa a kimentett értéket esp+10 címr l, ahol a sorozatszám második részéb l kiszámított adat van, majd összehasonlítja a most kiszámított értékkel. Ha egyezés van, akkor ezt eax regiszterben beállítja, ellenkez esetben eax 0 értéke nem változik. Ha most megnézzük a hívó eljárást, akkor látjuk, hogy pont eax értékét vizsgálja annak eldöntésére, hogy megfelel volt-e a regisztráció. Az algoritmus ismeretében a sorozatszám generátor megírását az olvasóra bízom. 38 5. A trialware programok A trialware programok által használt védelmek elemzésénél is olyan ötleteket vetek fel, ami megfordulhat egy szakértelemmel rendelkez programozó fejében. A védelem bemutatása mellett nagy hangsúlyt fektetek a támadhatóság kérdésére is, mely azonban nem jelenti azt, hogy minden konkrét program esetében

alkalmazhatók lesznek. Az el z fejezethez hasonlóan, itt szintén nem arra keresem a választ, hogy hogyan kell az ilyen programok védelmét kijátszani, hanem arra, hogy hogyan lehet. 5.1 Trialware programok felépítése Trialware program installálásakor a végfelhasználói szerz désben ki van kötve, hogy a program mely id tartamig, adott id pontig, vagy indítási számig használható ingyenesen. Az adott id tartamig teljes kör en használhatjuk a programot, azaz az összes funkciót kipróbálhatjuk szemben a shareware programokkal. Az, hogy még mennyi ideig használható a szoftver általában a program indítóképerny jén feltüntetik, de sokszor a Help About menüpontban is tájékoztatást kaphatunk. Mindenesetre a program lejárata fel fog t nni, ugyanis ilyenkor nem a szokásos módon indul el, hanem megjelenít egy információs ablakot, melyben közli, hogy a program lejárt. Az OK gombra kattintva a program futása befejez dik. Más gombra való kattintásra

nincs mód, vagy ha van, akkor az csak arra való, hogy az interneten megnézzük hogyan tudjuk beszerezni a teljes verziót. Ha jobban megnézzük a programot, sok esetben azt találhatjuk, hogy regisztrálásra nincs mód. 5.2 Trialware programok védelme Mivel a trialware programok védelme háromféle lehet, ezért a program védelmi módszereit is három különböz C programnyelven írt programrészlettel fogom szemléltetni. A f program mindhárom esetben megegyezik: void main() { if (!Check Date()) /* ellen rzés / { openExpiredWindow(); /* Közöljük, hogy lejárt a program / exit(0); /* kilépünk / } /* Még nem járt le a program, tehát indítható és teljes kör en használható */ /* további lépések */ exit(0); } 39 5.21 Fix napos id korlát védelem const MAXDAY=30; int Check Date() { date today date=getdate(); /* Mai dátum lekérdezése / openRegistry(); date inst date=getInstallation Date(); /* Installációs dátum / closeRegistry(); if (today date -

inst date<MAXDAY) /*Letelt a megengedett id ?/ { return 1; } /* Nem még nem járt le / else { return 0; } /* Igen már lejárt / } Ez a védelem tekinthet a legtöbbet használt módszernek. Installációkor feljegyz dik a telepítési dátum. A program minden egyes indításakor lefut ez az ellen rzés és megvizsgálja, hogy nem haladtuk-e meg az el re rögzített napok számát. Ha minden rendben van, akkor a program tovább futhat, ha nem, akkor tájékoztató üzenet küldése után kilépünk a programból. 5.22 Adott dátumig m köd védelem const EXP DATE=”2005.1212”; int Check Date() { date today date=getdate(); /* Mai dátum lekérdezése / if (today date<EXP DATE) /*Letelt a megengedett id ?/ { return 1; } /* Nem még nem járt le / else { return 0; } /* Igen már lejárt / } Ez a védelem ritkább, mint az el z . Inkább olyan béta programoknál alkalmazzák, amit ugyan kipróbálásra szánnak, de az adott id után már biztosan lesz a terméknek végleges

verziója. A védelem tulajdonképpen abból áll, hogy a program csak akkor indítható, ha az aktuális dátum nem haladja meg az el re beépített dátum értéket. 5.23 Adott indítási számos védelem const MAXSTART=20; int Check Date() { openRegistry(); int starts=getNumberofStarts(); /*Hányszor volt már elindítva / starts++; /* Most is elindítottuk / closeRegistry(); if (starts<MAXSTART) /*Letelt a megengedett indítási szám?/ { openRegistry(); updateRegistry(starts); /* Kiírjuk az új értéket / closeRegistry(); return 1; } /* Nem még nem járt le / else { return 0; } /* Igen már lejárt / } Ez a legritkább védelmi módszer a trialware programok körében. A program használata az indítási számtól függ. A program felfüggeszti a m ködését, ha elindítottuk már adott 40 alkalommal. Ez a védelem azért nem népszer , mert sokszor nem ad elég id t a termék részletes kipróbálására. 5.3 Trialware programok védelmének megkerülése A fenti

védelmek megkerülésére már több módszert is láthattunk. A fix id korlátos védelmet és az adott dátumig m köd védelmet a dátum visszaállítással (lásd 3.23 pont), az adott indítási számig m köd védelmet registry hack-kel (lásd 3.22 pont) a legtöbb esetben könnyedén megkerülhetjük. Az ilyen módszerek célravezet k, azonban nem kényelmesek, ritkább esetben esetleg nem is m ködnek. Így más módszert kell keresnünk. Láthattuk, hogy az ilyen programokat nem (mindig) lehet aktiválni, mint a shareware programok esetében, ezért jobbára a programkódot kell megváltoztatnunk. Mivel a védelem lényege arra korlátozódik, hogy a programot egy id után már ne tudjuk elindítani, ezért célunk csak az lehet, hogy a program minden esetben elinduljon. (Persze emellett általában az is cél, hogy minden zavaró tényez t is kiiktassunk, de ez csak esztétikai kérdés. Ilyen lehet például, hogy a program adott id letelte után indul csak el /counter

delay/.) Az indulás után a programra már nem vonatkoznak korlátozások, ezért ez a cél tulajdonképpen adott. Ezt háromféleképpen végezhetjük el Az egyik lehetséges megoldás, hogy a f programot módosítjuk. Láthatjuk, hogy a függvény visszatérésére vonatkozó feltételt kell módosítanunk. if (!Check Date()) /* ellen rzés / { openExpiredWindow(); /* Közöljük, hogy lejárt a program / exit(0); /* kilépünk / } Ez a módosítás viszont nyilvánvalóan nem lehet inverz m velet, mivel ha így járunk el a program csak a lejárat után fog elindulni. Azaz az assembly kódban a feltételes ugrás helyett feltétel nélküli ugrásra kell cserélnünk az utasítást, mégpedig úgy, hogy az ugrás mindig a „jó” ágra kerüljön. A következ elgondolás az, hogy a program adott konstans értékeit próbáljuk meg módosítani. Ezt körülbelül akkorára célszer beállítani, hogy a lejárat meghaladja az elévülési id t. Ez gyakran frissül programoknál

igen kis id S t néha még a program írói is olyan értékeket használnak, hogy el bb jelenik meg az újabb verzió, minthogy lejárna a régebbi (például a Nero Burning Rom, illetve fontosabb antivírus szoftverek). Mivel ezek az értékek konstans értéknek vannak definiálva, ezért nem az adatszegmensben helyezkednek el, hanem közvetlenül a kódba íródnak. Ez számunkra igen kedvez , mivel egyszer bb megtalálni, és javítani az adatot a kódszegmensben, mint az adatszegmensben. Például az 522 pontban bemutatott Check Date eljárásban szerepl konstanssal való összehasonlítás assembly nyelven a következ képp jelenhet meg: Check Date: call getdate mov eax, dword ptr[year now] cmp eax, 07D5 ; 2005. év jnge joag ; kisebb jg rosszag ; nagyobb mov eax, dword ptr[month now] cmp eax, 0C ;12. hó jnge joag ;kisebb mov eax, dword ptr[day now] cmp eax, 0C ;12. nap 41 joag: rosszag: vege: jg rosszag mov eax,1 jmp vege xor eax,eax ret ;nagyobb A harmadik megoldás

szintén a Check Date eljárásban található, de most nem a konstanst változtatjuk meg, hanem megpróbáljuk a feltételt módosítani. const MAXDAY=30; int Check Date() { date today date=getdate(); /* Mai dátum lekérdezése / openRegistry(); date inst date=getInstallation Date(); /* Installációs dátum / closeRegistry(); if (today date - inst date<MAXDAY) /*Letelt a megengedett id ?/ { return 1; } /* Nem még nem járt le / else { return 0; } /* Igen már lejárt / } A célunk az, hogy mindig „jó” ágra kerüljön a program futása, hisz így a f program is azt látja, hogy a program még nem járt le, így a futás folytatható. Mint a fenti assembly utasítás részletb l is jól látszik, összetett típusoknál ez az egyszer feltétel igazából több rész-összehasonlításokat takar. Azaz a feltétel megváltoztatásához esetleg több assembly összehasonlítást is meg kell változtatni. Célunk tehát nemcsak az, hogy „jó” ágra kerüljön a program

futása, hanem az, hogy ez miel bb megtörténjen. Látható, hogy a fenti assembly kód negyedik sora könnyen módosítható a jnge joag ugró utasításról a jmp joag utasításra. Már látjuk, hogy a trialware programok esetében mit kell módosítani3 a kódban, most nézzük meg, hogyan találhatjuk meg a konkrét részletet a kódban. Hasonlóan a shareware programokhoz el ször be kell „törnünk” a programba. Sejthet , hogy ez ott tehet meg könnyen, ahol valamiféle visszajelzés érkezik a felhasználó felé a program lejáratáról. Tehát, ha meg akarjuk keresni azt a feltételt, ami az indítást figyeli, le kell „járatnunk” a programot. Ez azt jelenti, hogy állítsuk a dátumot el re addig, amíg a program már nem lesz indítható. Ekkor a legtöbb esetben csak egy figyelmeztet ablakot kapunk, hasonlóan a shareware programoknál már látott „Registration incorrect!” ablakhoz. Tehát most már tudjuk, hogy a rossz ág esetén nem a program indul, hanem

a konkrét figyelmeztet ablak t nik el . Ezért állítsunk egy megszakítást az ablak megjelenítésére a debuggerünkben. A sikeres betörés után a hívás el tti kódot kell elemeznünk, és megtalálnunk a számunkra fontos elágazást, illetve esetleg a konstans összehasonlításokat. Az nem mondható el általánosan, hogy ez az elágazás hol található a kódban, de ha azt nézzük, hogy a program írója valószín leg az ellen rzés után egyb l hibajelzést küld, és nem a program további részeit építi, akkor elmondható, hogy a jelzés közvetlen környezetében található. Mindenesetre, ha a memóriában történt módosítás után nem a „lejárt” ablakot kapjuk, hanem a program szokásos módon indul, akkor garantáltan jó úton járunk. Ne felejtsük el, hogy a módosításokat a shareware programoknál már bemutatott módszerrel (lásd 4.33 pont vége) a konkrét indítható fájlban is el kell végezni 3 A tényleges módosítás részleteir l a

4.33 pontban már volt szó 42 5.4 Az Earth Recource Mapper 64 SP1 program elemzése A trialware programok védelmét gyakorlatban is bemutató rész következik. Választásom azért erre a programra esett, mert több, az ilyen programokra jellemz , védelemmel is ellátták, így érdekes lehet az elemzése. Az itt leírt módszerek csak és kizárólag tanulmányi céllal kerülnek ismertetésre! A kipróbálható verzió letölthet a http://tinyurl.com/cyw56 (20050531) oldalról 5.41 Ismerkedés a program védelmével A program indításakor a következ kép fogad minket: 13. ábra: A program védelmének vizuális megjelenése Láthatjuk, hogy a védelem elég egyértelm . Eredetileg a program 50 indítást engedélyez, és az installáció után 14 napig használható. Jelen esetben még 45 indításra van lehet ség, vagy ha ez nem következik be, akkor április 18-ig használható. Az els rádiógomb bejelölésével lehet séget kapunk az indításra. A többi opció

lehet séget ad beszerezni a licenc kulcsot, illetve megadni azt. Azt vehetjük észre, hogy a program tényleges elindítása nélkül a Close gombra kattintva az indítási szám csökkentve lesz. Ez még jobban lesz kíti az indítási lehet ségeinket. Ha a lejárat bekövetkezik, a következ információkat kapjuk: 14. ábra: Lejárt program 43 A szoftver közli velünk, hogy a további futtatáshoz állandó licencre van szükségünk, amit kérvényezhetünk is. Az indításhoz tényleg nem férhetünk hozzá, ugyanis ki van szürkítve ez az opció. A licenckérvényezés mellett csak a programból való kilépést választhatjuk, ami után a program tényleg nem indul el. 5.42 Felmerül stratégiák A dátum lejárat kikerülése érdekében a dátum visszaállítással próbálkozhatnánk, de ha kipróbáljuk, ez nem járható út, mivel a program figyeli ezt! Azt tapasztaljuk, hogy csak akkor indul el a program, ha a dátum nem haladja meg a lejárati dátumot,

ugyanakkor nagyobb, mint az utolsó indítás id pontja. Kés bb a kód vizsgálatakor kiderül, hogy a program azt is vizsgálja, hogy nem állították-e el rébb, mint az installációs dátum. Így még azt sem lehet eljátszani, hogy installációkor egy távoli id re állítjuk a dátumot, majd futtatáskor már az aktuális id t használjuk. Ebb l lesz rhetjük, hogy a program két információt biztosan elment, mégpedig az installációs dátumot és az utolsó indítás dátumát. A védelem láttán nagyon örültem, hogy a más programokban nem figyelt dátum visszaállítást ez a szoftver figyeli. Az 50 indítás ellen sem lehet mit tenni, valahova ez is mindig elment dik. A program lejárata után hiába próbálkozunk az újratelepítéssel, az adatok meg rz dnek és továbbra sem lehet használni a programot. Azaz egy egyszer felhasználó ellen azt mondhatjuk, hogy nagyon is védett a program. Megpróbálkozhatunk feltérképezni a registry bejegyzéseket. A [HKEY

CURRENT USER] ág alatt a program Earth Resource Mapping néven helyez el bejegyzéseket, melyek láthatóan csak néhány ablak elhelyezés koordinátára, és az installációs könyvtárra vonatkozva tartalmaz adatot. Nagyobb szerencsével járunk a [HKEY LOCAL MACHINE] ágban, ahol hasonló kulcs alatt érdekes bejegyzést találunk ERMAPPER AUTH néven. Ebben a kulcsban egy sztring adat szerepel egy 40 karakter hosszú kóddal megadva. Valószín síthetjük, hogy ez a kulcs szolgáltatja az evaluation licencünket. Jobban körülnézve azonban semmi olyan kulcsra nem figyelhetünk fel, ami talán a dátumokra, illetve az indítási számra vonatkozhatna. Így azt kell feltételeznünk, hogy ezeket az adatokat a program egy (vagy több) fájlban tárolja. Megpróbálkozva az eltávolítással, majd a programra vonatkozó maradék regisztrációs bejegyzések törlésével, megpróbálhatunk olyan környezetet teremteni, hogy azt higgye a program most lesz telepítve el ször. Az

installációt követ indításkor viszont azt tapasztaljuk, hogy a Licensing wizard azt mondja, hogy nem lehet megállapítani a licencünk státuszát. Ez természetesen azzal jár, hogy a programot sem futtathatjuk tovább. Ha ezután beletekintünk a registrybe, akkor láthatjuk, hogy hiányzik a mágikus ERMAPPER AUTH kulcs. Azaz az installációs program nem generálta le számunkra, mint az els alkalommal. Mivel elvileg a szoftverhez tartozó összes fájlt és regisztrációs bejegyzést eltávolítottuk, ezért fel kell tennünk, hogy ezen kívül is kezel még olyan fájlokat a program, ami nem a saját mappájában van elhelyezve. Ilyen fájlokat elrejteni a rendszerben a windows könyvtára kiválóan alkalmas, így figyelmünk is erre terel dhet. Nem kell mást tennünk, mint el keresni azokat a fájlokat, amik aznap módosultak. Így már nem nehéz rálelni arra a fájlra, ami a windows könyvtár ER MAPPER rejtett könyvtárba lett elhelyezve ermapper.dll néven A fájl

neve megtéveszt , ugyanis ez nem egy dll fájl inkább egy konfigurációs állományra hasonlít er sen kódolva. Nagyon nagy valószín séggel feltehet , hogy ide ment dik az installációs dátum, az utolsó indítási dátum, és az indítási szám is. Érdekes, hogy egy még m köd állapotú program esetében a fájl elmentése, majd kés bbi visszaállítása licenc hibához vezet. Tovább keresgélve a windows könyvtárban, még ráakadunk a system32 (win98 alatt a system) könyvtárban egy ERM könyvtárra, melyben szintén a program egyes fájljai vannak. A regisztrációs adatbázisban ezekre a fájlokra rákeresve 44 azt kapjuk, hogy az említett fájlok osztott dll-ek, vagyis több felhasználós alkalmazásfuttatáskor lesznek felhasználva. Az utolsó a szoftverhez kapcsolható rejtett fájl a windows system32 könyvtárában helyezkedik el nebualre.ind néven Megtekintve ezt a fájlt láthatjuk, hogy pont az a 40 karakteres kód van benne, mint ami jobb esetben

a regisztrációs adatbázisba bejegyzésre került. Feltehet , hogy installációkor ezt a fájlt figyelte a program, és abban az esetben, ha talál ilyet, akkor nem teszi azt be a regisztrációs adatbázisba. Törölve azonban ezeket a fájlokat is, már sikeresen telepíthetjük újra a szoftvert. Egy közepesen képzett felhasználó illetve szakember számára tehát a védelem (legális módszerekkel) már megkerülhet , a használat ideje kiterjeszthet . A következ alfejezetek azt mutatják be, hogy magasabb szinten hogyan lehet befolyásolni a szoftverben alkalmazott védelmeket, megvizsgálva a védelem konkrét algoritmusát is. 5.43 A kód elemzése Mivel a védelem legel ször a Licensing wizard képében kerül elénk, ezért ezt a programot vizsgáljuk közelebbr l. A disassembly kód el állítása után (licensingwizard.exe) nézzük meg a szöveg referenciákat Mivel a lejárat tényét egy szöveg közli, ezért rákereshetünk a „Your evaluation license has now

expired.” szöveg el fordulására. A keresés a következ kódrészletet hozza: * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00411C56(C), :00411C62(C) | * Possible Reference to String Resource ID=00167: „Your evaluation license has now expired. You can request a p" | :00411CA1 68A7000000 push 000000A7 :00411CA6 E91CFFFFFF jmp 00411BC7 Látjuk, hogy a program futása két helyr l is ide ugrik, tehát derítsük ki, hogy mi alapján dönti ezt el. * Reference To: MSVCRT.time, Ord:02D0h | :00411C46 FF1568844100 Call dword ptr [00418468] :00411C4C 8B7C2438 mov edi, dword ptr [esp+38] :00411C50 83C404 add esp, 00000004 :00411C53 6685FF test di, di ; maradék futási szám :00411C56 7449 jz 00411CA1 :00411C58 8B5C2430 mov ebx, dword ptr [esp+30];lejárat dátuma :00411C5C 8B542418 mov edx, dword ptr [esp+18];mai dátum :00411C60 3B13 cmp edx, dword ptr [ebx] :00411C62 7F3D jg 00411CA1 Ha figyelmesen megvizsgáljuk a kódot láthatjuk, hogy az egyik a

futási számot vizsgálja, a másik pedig a dátumot veti össze. Ez persze nem triviális, de majd a debuggerben vizsgálva a memória tartalmakat is láthatjuk, és onnan már könnyebb következtetni erre. A másik ok arra, hogy ezt a következtetést vontuk le az, hogy tudjuk miért írja ki ezt a szöveget a program. Nyílván az egyik lehetséges ok, ha lejárt az összes indítási számunk (láttuk, hogy az indítási számot mindig csökkentve írja ki a 45 program), vagy ha az indítási dátum nagyobb a megengedettnél (jelen esetben a telepítést l számított 14 nap). Nézzük meg mi történik, ha egyik helyen sem teljesül az ugrás feltétele. :00411C64 55 push ebp * Possible Reference to String Resource ID=00152: „You are currently running ER Mapper in evaluation mode. To r" | :00411C65 6898000000 push 00000098 :00411C6A 8D4C2414 lea ecx, dword ptr [esp+14] Láthatjuk, hogy az a kiírás fog megjelenni, ami a lejárat el tt jelent meg, azaz egy olyan

irányt találtunk, amerre mindenképp menni kellene (legalábbis els megközelítésben). A kódból egyel re nem tudunk meg többet, ezért most nézzük meg a programfutást debuggerben is. Ahhoz, hogy valahogy be tudjunk tekinteni a programba, egy megszakítást kell állítani valamire. Ha megnézzük, hogy a wizard milyen küls függvényt használ, láthatjuk, hogy lekérdezi a dátumot a vizsgálat el tt. Tehát állítsunk majd figyelést a dátumlekérdezésre (getsystemtime). Az indítás el tt bizonyosodjunk meg arról, hogy a program éppen a lejáratot közli velünk, majd állítsuk be a figyelést. Az indítás után többször megszakad a futás (más is hivatkozik erre a függvényre), de el bb-utóbb eljutunk a Licencing wizard kódjához is. Ez a hely nem biztos, hogy az, ahol mi szeretnénk tenni, de nincs nagy baj, mert már tudjuk, hol kell keresni a kódot. Nézzük meg a kódszegmens 411C46 sorát és állítsunk rá figyelést, a dátumfigyelést pedig

szüntessük meg. Ha ez sikerült a további futás után pont ott szakad meg, ahol mi akartuk. Lépegessünk végig a kódon soronként (step over) Ha még nem telt le az 50 indítás, akkor látjuk, hogy az els ugróutasításon sikeresen túljutunk. A másodiknál azonban mindenképp ugrani akar a program. Változtassuk meg az „s” flaget, ami azt eredményezi, hogy az ugrás nem történik meg. Hagyjuk tovább futni a programot és figyeljük meg az eredményt. Látható, hogy a szöveg úgy változik, ahogy akartuk, de az indításra engedélyt adó rádiógomb kiszürkül! Ez azt jelenti, hogy máshol is van egy az el bbiekhez hasonló vizsgálat, ami kezeli a rádiógomb tulajdonságát. Lépjünk ki a programból, majd indítsuk el újra. A program futása megszakad a szöveg vizsgálatnál, megint menjünk végig soronként, és irányítsuk úgy a futást, ahogy az el bb, de ezután kapcsoljuk vissza a dátumlekérdezésre a figyelést. Miután ez megvan, hagyjuk tovább

futni a programot. Ha jól jártunk el, akkor a következ kódrészletnél lyukadunk ki: * Reference To: MSVCRT.time, Ord:02D0h | :00411F2E FF1568844100 Call dword ptr [00418468] :00411F34 8B07 mov eax, dword ptr [edi] :00411F36 83C404 add esp, 00000004 :00411F39 83F803 cmp eax, 00000003 :00411F3C 750F jnz 00411F4D :00411F3E 66837D0000 cmp word ptr [ebp+00], 0000;futási szám :00411F43 741F jz 00411F64 :00411F45 8B4C2410 mov ecx, dword ptr [esp+10]; mai dátum :00411F49 3B0B cmp ecx, dword ptr [ebx] :00411F4B 7F17 jg 00411F64 A második rész a már ismert dátum összehasonlítás, látjuk, hogy ha nagyobb a dátum, akkor ugrik a tiltás felé. Ha figyelmesek vagyunk, akkor észrevesszük, hogy fölötte ugyanez az ugrás található, ez vizsgálja az indítási számot egy kicsit másképp, mint az el z részben, mivel itt nem kell regiszterbe töltenünk a címet a kiíratáshoz. Vonjuk 46 vissza a dátumhívás figyelését. Ha megfelel en módosítjuk az ugrási

feltételeknél a haladási irányt, akkor láthatjuk a végeredményt: A lejárat el tti szöveg és az engedélyezett rádiógomb! Az indításra kattintva azonban nem várt eredményt kapunk, a program kilép. Ez egyet jelenthet: még valahol be van építve egy dátumfigyelés! A megoldáshoz járjunk el az el bbi módon, de most állítsuk vissza a dátumlekérdezés figyelését, miel tt megnyomnánk a Finish gombot. Ha így járunk el, akkor a futás a következ kódrésznél megáll, az ERMAPPER kódjában! * Reference To: MSVCRT.time, Ord:02D0h | :1003A038 FF154C531910 Call dword ptr [1019534C] :1003A03E 8B4508 mov eax, dword ptr [ebp+08];mai dátum :1003A041 83C404 add esp, 00000004 :1003A044 3BC6 cmp eax, esi ; vs lejárati dátum :1003A046 7F34 jg 1003A07C :1003A048 3B450C cmp eax, dword ptr [ebp+0C];vs utolsó :1003A04B 7C2F jl 1003A07C :1003A04D 3B45A8 cmp eax, dword ptr [ebp-58];vs install :1003A050 7C2A jl 1003A07C Ha megfigyeltük a f program indulásakor, hogy több

program is elindul egyszerre, akkor nem leszünk meglepve azon, hogy a Licencing wizard kilépése után az Ermapper kódjába kerülünk. Az adott programrészletet vizsgálva kiderül, hogy a vizsgálatok az aktuális dátumot veszik célba. Az els ismer s lehet, megvizsgálja, hogy nem léptük e túl a lejárat dátumát, a harmadik azt vizsgálja, hogy az installációs dátum el tt vagyunke. A második azt figyeli, hogy az utolsó indítás óta visszaírtuk-e a dátumot kevesebbre! Azaz a program figyeli a dátum visszaállítását! Ha bármelyik feltétel sérül, a szoftver befejezi futását. Módosítsuk úgy a futást, hogy ne teljesüljön az ugrás (jl esetében az „c” flaget kell állítanunk, ha szükséges). Ha így tovább engedjük a futást, akkor a program nem lép ki, hanem elindul. Ha az els dleges célunkat tartjuk szem el tt (miszerint a program mindig indítható legyen), akkor végeztünk a vizsgálattal, a Licencing wizardban 8 bájtot, az Ermapper

(dll)-ben 6 bájtot kell NOP (90h) utasításra cserélni. Most részletesen vizsgáljuk meg közelebbr l a felhasznált védelmeket. 5.431 Indítási szám vizsgálata A Licencing wizard két ponton is vizsgálta a program indítási számát. Egészen pontosan a még visszamaradt indítási számot olvassa ki a memóriából. Most azt fogjuk megvizsgálni, hogy ezt az értéket hol számolja ki a program, és hogyan lehet esetleg ezt befolyásolni. Ugyanis, ha sikerül megváltoztatni az ott lév értéket valami pozitív számra, akkor nem lesz szükség az ugrás utasítás felülírására. Ahhoz, hogy meghatározzuk azt a programkód részletet, ahol a memóriába való írás megtörténik meg kell néznünk, hogy mit takar a :00411C4C 8B7C2438 mov edi, dword ptr [esp+38] utasításban a memóriacím. Ez a cím minden rendszerben más lehet, például: 17F:6CDB60 esetleg. Erre a memóriacímre állítsunk egy memóriaírás figyelést, és indítsuk el a programot. A futás

többször is megszakadhat, de minket csak abban az esetben érdekel, ha a beírt érték a maradék indítási száma hexadecimálisan (például: 13 indítás esetén 0Dh). Esetleg több próbálkozást is végig kell nyomozni, míg el nem jutunk a következ programrészhez az ERMAPPER kódban. 47 :1003B837 :1003B83A :1003B840 :1003B845 :1003B847 :1003B849 :1003B84B :1003B84E :1003B84F :1003B851 8B55FC 81E2FFFF0000 B832000000 2BC2 33D2 85C0 0F9EC2 4A 23D0 668911 mov edx, dword ptr [ebp-04] and edx, 0000FFFF;hányszor indították mov eax, 00000032;max indítási szám sub eax, edx xor edx, edx test eax, eax setle dl dec edx and edx, eax mov word ptr [ecx], dx A részlet utolsó sora vonatkozik arra, hogy az eredményt kiírja a megadott memóriarészre. Az el tte lév rész vonatkozik a kiszámításra Az eddigi indítási számot edx regiszterbe tölti, majd a regiszter fels felét kinullázza, eltüntetve ezzel a benne lév szemetet. Ezután jön az, hogy eax-ba 32h konstans

értéket tölt, ami decimálisan éppen 50-et ad! Ebb l levonjuk az indítási számot, amit végül kiírunk a memóriába. Látható, hogy csak az alsó 2 bájt kerül kiírásra, tehát, ha esetleg változtatnánk a konstanson, akkor a legnagyobb érték, amit kiírhatnánk FFFFh lenne, ami 65535 indítást jelent.4 Ha ez nem elfogadható, akkor a sub eax,edx kódon kell megfelel en (például mov eax,eax) változtatni. 5.432 Lejárati dátum vizsgálata A lejáratot a program már egy adott memóriacímr l olvassa, tehát ez is máskor lett már kiszámolva. Szeretnénk a lejárat dátumát a lehet legtovább kitolni, így biztosítva, hogy az ugrás feltételeket ne kelljen változtatni. :00411C60 3B13 cmp edx, dword ptr [ebx] Ez az ebx által mutatott memória cím a 17F:6CEEAC (ez változhat). Ha erre egy memóriafigyelést állítunk, akkor az el bbi pontban leírtakhoz hasonló módon juthatunk a következ ERMAPPER kódrészlethez. :1003B80B :1003B80E :1003B813 :1003B816

:1003B819 :1003B81C :1003B81F :1003B820 :1003B823 :1003B826 :1003B828 8B45E8 25FFFF0000 8D0440 8D0480 8D0480 8D04C0 56 8B75EC C1E007 03C6 8901 mov eax, dword ptr [ebp-18];0Eh and eax, 0000FFFF lea eax, dword ptr [eax+2*eax] lea eax, dword ptr [eax+4*eax] lea eax, dword ptr [eax+4*eax] lea eax, dword ptr [eax+8*eax] push esi mov esi, dword ptr [ebp-14] shl eax, 07 add eax, esi mov dword ptr [ecx], eax A részlet utolsó sora mutatja, hogy hol kerül kiírásra a memóriába a lejárati dátum. Az elejét vizsgálva láthatjuk, hogy eax regiszterbe tölt dik az ebp-18 címen tárolt érték, ami 0E hexadecimális szám lesz. Ez jelenti a megengedett napok számát, hisz ez decimálisan 14-et jelent. Ezután az értéket datetime formátumra konvertálja, majd betölti esi-be az aktuális dátumot és hozzáadja a konvertált értékhez. Végül kimenti a memória címre. Ezen a kódon túl sokat nem érdemes változtatni, hisz a konstans érték máshol került a memóriába. Ezért

az ebp-18 (17F:6CDB38) -as címre is állítsunk egy figyelést Csakhamar kiderül, hogy a következ kódrészlet írja be a memóriába az értéket: 4 Ez az érték napi 3 indítást feltételezve 21845 (csaknem 60 év!) napot jelent. 48 * Referenced by a (U)nconditional |:1003B4A8(C) | :1003B4CF 8B4510 :1003B4D2 C70001000000 :1003B4D8 66C740040E00 :1003B4DE EB14 or (C)onditional Jump at Address: mov mov mov jmp eax, dword ptr [ebp+10] dword ptr [eax], 00000003 [eax+04], 000E 1003B4F4 Az itt megadott értéket már könnyen módosíthatjuk például 2EC9h-ra, ami 11977 napot (32 év!) jelent. Ne felejtsük el azonban, hogy ez a vizsgálat csak a Licencing wizardra vonatkozik, hisz láttuk már, hogy dátum ellen rzés máshol is el fordul. Ezt több módszerrel is megtalálhatjuk, például a mai dátum helyére való hivatkozás figyelésével. Ez a kód egyébként azon kódrész felett helyezkedik el, ahol az ERMAPPER kódját el ször vizsgáltuk. :1003A018 :1003A01B

:1003A01E :1003A023 :1003A026 :1003A029 :1003A02C :1003A02F :1003A032 :1003A035 :1003A036 8B45A4 8B5DA8 25FFFF0000 8D0440 8D0480 8D0480 8D34C0 8D5508 C1E607 52 03F3 mov eax, mov ebx, and eax, lea eax, lea eax, lea eax, lea esi, lea edx, shl esi, push edx add esi, dword ptr dword ptr 0000FFFF dword ptr dword ptr dword ptr dword ptr dword ptr 07 [ebp-5C] ;0Eh [ebp-58] ;inst dat [eax+2*eax] [eax+4*eax] [eax+4*eax] [eax+8*eax] [ebp+08] ;mai dat ebx * Reference To: MSVCRT.time, Ord:02D0h | :1003A038 FF154C531910 Call dword ptr [1019534C] :1003A03E 8B4508 mov eax, dword ptr [ebp+08] :1003A041 83C404 add esp, 00000004 :1003A044 3BC6 cmp eax, esi :1003A046 7F34 jg 1003A07C A kódrész nagyban hasonlít az el z kódhoz, amit már vizsgáltunk, csak itt nem ment dik el az érték, hanem egyb l összehasonlításra kerül. Itt is látjuk, hogy a konstans érték nem itt kerül a memóriába, tehát meg kell keresni azt a helyet, ahol beleírja az értéket. Ezt a részt a többihez analóg

módon megtalálhatjuk: * Referenced by a (U)nconditional |:10039C42(C) | :10039C6A C745A003000000 :10039C71 66C745A40E00 :10039C77 EB17 or (C)onditional Jump at Address: mov [ebp-60], 00000003 mov [ebp-5C], 000E jmp 10039C90 Tehát az itt átírt érték fog arra vonatkozni, hogy a program valóban elindulhat-e. 5.433 Ínyencségek Az el z pontban láthattuk, hogy a konstans nap elhelyezése mellett valami mást is kiment a program. Ahhoz, hogy megértsük ennek a konstansnak a jelentését, vissza kell mennünk a program vizsgálatának elejére. Nézzük, milyen szöveg konstansokat találunk a Licencing wizard kódjában: 49 :00411BB9 :00411BBB :00411BBE :00411BC3 8B00 83F801 C644242402 7529 mov cmp mov jne eax, dword ptr [eax] eax, 00000001 [esp+24], 02 00411BEE * Possible Reference to String Resource ID=00120: „You currently have a permanent license to run ER Mapper. " :00411BC5 6A78 push 00000078 Azaz ha a licenc típus 1-nek van beállítva, akkor egy

állandó jelleg licencünk van. :00411BEE 83F802 :00411BF1 7549 cmp eax, 00000002 jne 00411C3C * Possible Reference to String Resource ID=00151: „You currently have a temporary license to run ER Mapper." | :00411BF3 6897000000 push 00000097 :00411C23 8D8674010000 lea eax, dword ptr [esi+00000174] * Possible StringData Ref from Data Obj->„%s This license will expire on " ->„%s" | :00411C29 6804FB4100 push 0041FB04 Ha a licenc típus 2-es, akkor egy ideiglenes licencünk van, ami kés bb lejárhat. :00411C3C 83F803 :00411C3F 756A ; lejárat vizsgálata :00411C62 7F3D :00411C64 55 cmp eax, 00000003 jne 00411CAB jg 00411CA1 push ebp * Possible Reference to String Resource ID=00152: „You are currently running ER Mapper in evaluation mode. To r" | :00411C65 6898000000 push 00000098 Ha a licenc típus 3-as, akkor egy kipróbálható verziónk van, aminek kiírása el tt lefut a már elemzett ellen rzés. :00411CAB 85C0 :00411CAD 7510 test eax, eax

jne 00411CBF * Possible Reference to String Resource ID=00153: „You currently do not have a license to run ER Mapper. If you" | :00411CAF 6899000000 push 00000099 Ha a licenc típusunk 0-s, akkor nincs licencünk. A teszteléshez használt eax regiszterbe az adat ugyanarról a memória címr l kerül beolvasásra, mint ahova az el z pontban az eljárás a 3-as konstans adatot mentette. A következmény megfogalmazását az olvasóra bízom. 50 6. A demoware programok 6.1 A demoware programok felépítése A dolgozatom témájához er sen köt d demoware programok tulajdonságait is szeretném bemutatni, hogy szemléltessem a shareware és trialware programokhoz f z d kapcsolatát, ugyanakkor felhívjam a figyelmet, hogy az ilyen programok gyakorlatilag törhetetlenek. A demoware programokat is az eredeti program bemutatójának szánják. Ha feltelepítünk egy demoware szoftvert, akkor azt fogjuk tapasztalni, hogy néhány funkció nincsen meg a programban, vagy „le

van tiltva”. Persze ez csak az eredeti program ismeretében t nik fel, illetve a dokumentációban írják le, hogy az eredeti verzióban mi található meg, ami a demo verzióban nem került implementálásra. Ez sokakat a shareware programokra emlékeztetheti, de a megvalósítás itt alapjaiban más. Az ilyen programok semmilyen körülmény között sem tehet k teljes m ködés vé. A demo programokat nem lehet hagyományos módszerrel aktiválni sem Legtöbbször nagyobb programokból (például játékszoftverek) készítenek demo verziót, mivel az ilyen verziók lényegesen kevesebb helyet foglalnak, így könnyebben terjeszthet k, letölthet k az internetr l. Speciálisan a játékszoftverekben a demo azt jelenti, hogy csak néhány pályát próbálhatunk ki, esetleg limitált karakterekkel. Ahhoz, hogy a demo program teljes kör en m ködjön, be kell szereznünk a boltban, vagy egy disztribútornál a teljes verziót. 6.2 A demoware programok el nyei A demoware

programoknak számtalan el nye van. Az a tény, hogy a programok hiányos eljárásokat tartalmaznak, két jó dolgot is jelentenek. Az egyik, hogy a lefordított program lényegesen kevesebb helyet foglal, mint az eredeti szoftver. Így sokkal hordozhatóbbá válik és könnyebben terjeszthet . A másik, hogy a letiltott vagy hiányzó programrészeket nem lehet pótolni, azaz nem lehet a programot crack-el teljes verziójúvá változtatni. Ez a program írói számára jelent s értékkel bír, hisz a shareware programokhoz hasonló színvonalon nyújthat eszközt a program kipróbálására, azonban a teljes verzióhoz legálisan csak boltban juthatunk hozzá5. 6.3 A demoware programok hátrányai A demoware programok hátrányai eredend en a programok el állításának módszereib l fakadnak. Tudnunk kell, hogy a legtöbbször kétféleképpen állítanak el demo programot az eredeti szoftverb l. Az els módszer az, ha a fejlesztés során létrehozott kódot használják fel,

mégpedig a teljes id tartam felénél vagy háromnegyedénél. Nyilvánvaló, hogy ez magában hordozza azt a hátrányt, hogy a program nem elég kiforrott, és még igen sok hiba lehet benne. Erre sokszor figyelmeztetnek is a gyártók, de például egy játék fanatikusnak a demo verzió is nagyon sokat ér. Ha hiba van a szoftverben, könnyen azt gondolhatjuk, hogy majd a végleges verzióban javítva lesz. 5 Az úgynevezett warez oldalakról azonban illegálisan továbbra is letölthetjük a teljes verziójú szoftvereket. 51 A második módszer az, hogy az eredeti kész programot „butítják”. Ez konkrétan azt jelenti, hogy az egyes nem kívánt eljárásokat nem a programban tiltják le, hanem gyakorlatilag fizikailag is eltávolítják. Ennek két hátránya van Az egyik igen nagy hátrány, hogy az el állítás így nagyon drágává válik. A már megírt programrészleteket úgy kell eltávolítani, hogy az a maradék program helyes m ködésére ne legyen

hatással. Ezt körültekint eljárással is nagyon nehéz megvalósítani, és mivel a demo programhoz semmiféle támogatottság nem jár, ezért valószín leg a visszamaradt programrészt nem vetik olyan teljes kör tesztelés alá, mint az eredeti programot. Ez viszont felemás érzéseket szülhet a felhasználóban, hisz hiba esetén azt gondolhatja, hogy ha a demo verzió ilyen hibás, akkor milyen lehet az eredeti. Így nem biztos, hogy jó reklám egy esetlegesen nagyon is jól m köd programnak egy hibás demo verzió. 52 7. Fejl déstörténet 7.1 Régebben használt szoftvervédelmi módszerek A számítástechnika fejl désének legelején is igény mutatkozott arra, hogy a szoftvereket védelemmel lássák el. Mivel a hardver mit sem ér szoftver nélkül, ezért a szoftvereknek most is, és akkor is értékük volt. Régebben az egyedüli adathordozó a hajlékony lemez volt, ezért arra törekedtek, hogy az esetlegesen lemásolt szoftverek ne m ködjenek úgy,

mint az eredetiek. Ezt többféleképpen próbálták megvalósítani, a legjobban m köd , hatékony ugyanakkor nagyon széls séges módszer az volt, hogy a szoftverbe vírust építettek. Ha a programot egy másolt adathordozóról indították, a vírus aktivizálódott, a memóriába tölt dött (rezidens kód), majd az összes további adathordozót végigfert zte. Végül egy adott id ben lefuttatott egy büntet rutint. Ez lehetett akár egy véletlenszer en végrehajtott újraindítás, de rosszabb esetben akár magát az adathordozót is megsemmisíthette. A merevlemezes egységek megjelenése még nagyobb teret nyitott a vírusok terjedésének. Ma már tudjuk, hogy az eredetileg programvédelemre szánt módszer egy teljes „iparággá” n tte ki magát, jelen napokban a hálózaton terjed kártékony programkódokkal kell megküzdenie az embereknek nap, mint nap. S bár a mai vírusoknak kevés közük van a programvédelemhez, jelent s bevételhez juttatják a

vírusirtó szoftverek fejleszt it. Miután a személyi számítógépek ára olyan szintre esett, hogy az átlagember számára is megfizethet vé vált, a szoftverek is elkezdtek szaporodni. A gyors terjesztés viszont nem volt megoldott, ezért a programok védelmére eleinte nem is fektettek hangsúlyt. Az id el rehaladtával viszont egyre több embernek lett gépe, és az ismertebb programok kézr l kézre jártak. Ezt felismerve a gyártók megpróbáltak másolásvédelmet építeni a szoftverükbe, amit valójában nem csak a program tartalmazott, hanem az adathordozó is. Ilyen volt például az, hogy a hordozó lemezen szándékosan elhelyeztek egy olvashatatlan részt (bad sector), amit a program induláskor mindig leellen rzött. Ha nem találta meg, akkor jogosan feltételezte, hogy illetéktelen felhasználó próbálja meg futtatni. Másolásvédelmi megoldásokkal még napjainkban is gyakran találkozhatunk, annak ellenére, hogy ma már törvény mondja ki, hogy a

gyártó nem akadályozhatja a szoftverr l való biztonsági másolat készítését (lásd b vebben 1.2 fejezet) Az információs technológia gyors fejl déseként egyre több igény érkezett sokréteg programok használatára. A gyártóknak csakhamar szembesülniük kellett a piac telít désével. A shareware, trialware és demo programok megjelenését az okozta, hogy a programok száma már annyira megn tt, hogy csak úgy lehetett értékesíteni ket, ha azt kipróbálásra eljuttatják a leend felhasználók felé. Ennek a koncepciónak kedvezett az is, hogy az adathordozók egyre korszer bbek lettek (így szakújságok mellékleteként könnyen terjeszthet kké váltak), s t az internet megjelenésével gyakorlatilag mindenkihez azonnal eljuttatható lett a program. 7.2 A jöv védelmi módszere Az internet megjelenésével a gyors terjesztés ugyan megoldott lett, ugyanakkor visszajutottunk, ahhoz a múltbeli problémához, hogy a gyors hálózaton az emberek 53 egymás

között osszák meg a birtokolt programjaikat. A másolásvédelmet itt nem alkalmazhatja a fejleszt , ezért más eljárásokat kell kidolgozni. Manapság nagyon népszer a szoftver interneten való aktiválása. Ez jobb esetben arról szól, hogy a kapott regisztrációs kódot a program nem önállóan ellen rzi, hanem az interneten egy távoli eljárás segítségével végzi azt. Így megel zhet a sorozatszám generátorok írása, hisz maga az ellen rzési algoritmust nem tartalmazza a program. További el ny, hogy a többször felhasznált sorozatszámok begy jthet k és központilag letilthatók. Ugyanakkor az ilyen ellen rzések a crack ellen továbbra is védtelenek, hisz a visszatérési érték továbbra is „hamisítható”. Rosszabb esetben az internetes aktiváláskor egy regisztrációs bejegyzést kapunk, ami alapján már tudná a program, hogy aktivált. A vizsgált módszerek alapján tudjuk, hogy ez sem lehet megoldás, hisz el tudjuk (crackkel) érni, hogy

induláskor a vizsgálat sikerüljön. Érdemes figyelmet fordítani a java programok felépítésére. Ugyanis az ilyen programok bináris állományai igazából köztes tárgykódok, melynek utasításait egy virtuális gép hajtja végre, vagyis a debuggerben megfigyelhet programviselkedés nem biztosítja azt, hogy a program konkrétan ilyen utasításokat használ. S t, ha megtalálnánk a konkrét kódot a memóriában, amit módosítani szeretnénk, akkor is bajban vagyunk, hogy a tárgykódban vajon a módosítást hol kellene elvégezni. Azonban a tárgykód felépítése már ismert, így már van olyan program (java decompiler), mely a tárgykódból (class) konkrétan visszaállítja a forrásprogramot (java). A java alkalmazásokhoz hasonlóan a .NET alkalmazások is köztes tárgykódba fordítódnak, azonban ezeket a tárgykódokat nem virtuális gép hajtja végre. Mégis itt is az a kérdés, hogy hol és mit kellene a kódban módosítani. Valószín leg a közeljöv

ben erre is választ fogunk kapni. Az, hogy a jöv ben milyen védelmi módszereket találnak ki a fejleszt k, nehéz megmondani. Elmondható, hogy a múltban, jelenben és a közeljöv ben sem létezhet olyan védelem, amit ne lehetne megkerülni. Klasszikus szóhasználattal élve azt is mondhatnánk, hogy minden zárnak megvan a nyitja. A shareware és trialware programok jelenlegi felépítése nem teszi lehet vé, hogy olyan védelmet lehessen bennük alkalmazni, amit ne lehetne megkerülni. Az én javaslatom szerint azonban érdemes lenne arra törekedni, hogy a feltörésre szánt id t megpróbáljuk maximalizálni. A következ kben olyan módszereket vázolok fel, melyek használatával esetleg ki lehetne tolni a feltörésre szánt id t. A jöv ben használt védelmekben nagy szerepet kaphat az internet. Mivel ez a hálózat folyamatosan n , egyre több ember kapcsolódik hozzá, akkor is, ha nem használja azt (például adsl, vagy kábelmodemes eléréssel). Valószín nek

tartom, hogy ezt a tényt a szoftvergyártók ki fogják használni úgy, hogy a szoftver csak akkor legyen használható, ha az a szerverükhöz kapcsolódik, és folyamatosan hitelesítik azt. A probléma ezzel még nem oldódik meg, hisz ezt a figyelést is ki lehet iktatni. Ezek szerint a programot úgy kell megírni, hogy mindenképpen kapcsolódni kelljen a szerverhez. Ezt úgy lehetne elérni, hogy a programunkat két részre bontva kliensszerver modellben írjuk meg A program szerver része a fejleszt kiszolgálóján fut, a kliens pedig a felhasználó gépén. A kliens programot úgy írjuk meg, hogy önmagában is m köd képes legyen, így gyakorlatilag egy shareware programhoz hasonló tudású programot adunk kipróbálásra. Azonban, ha az egyéb eljárásokat is kívánja használni a felhasználó, akkor muszáj kapcsolódnia a szerverhez, és mint távoli eljárást kell lefuttatni a kérést, mely regisztrált felhasználó esetében végrehajtódik, egyébként

pedig hibaüzenetet küld. A megoldáshoz azonban elengedhetetlen az állandó internet kapcsolat viszonylag hibamentes és gyors adatáramlással. A hálózat gyorsulásával esetleg az is lehet vé válna, hogy a felhasználó nem kapja meg a fizikai fájljait a programnak, hanem egy távoli szerverr l érhetné el úgy, hogy 54 gyakorlatilag onnan futtatná azt. Ez azt jelenti, hogy futtatási jogot csak azok kaphatnának, akik regisztráltak, ugyanakkor olvasási jogot senki sem kapna. Azt, hogy ki tekinthet regisztrált felhasználónak, nem felhasználó+jelszó kombinációval kell ellen rizni, hanem egyedi kulccsal. Ezek lehetnek a már létez hardverkulcsok, de akár a jöv ben megjelen egyéb eszközök is, mint például digitális ujjlenyomat leolvasó, vagy írisz szemvizsgálat. Nyilvánvaló, hogy ezek a hitelesítési eljárások sem megkerülhetetlenek, hisz az eredményt nagy valószín séggel hamisítani tudjuk. 55 8. Összefoglalás Az el z fejezetekben

megvizsgáltuk a Shareware és Trialware programok védelmének felépítését. Megtárgyaltuk, hogy a programokban jellemz en hol helyezkednek el a védelmi kódok, majd kitértünk arra, hogy ezek ismeretében mennyire játszhatók ki ezek a védelmek. Láttuk, hogy a kétféle licenc típus legnagyobb hibája, hogy valamilyen szinten a teljes m köd képes programkód a felhasználóhoz jut, így tetsz legesen befolyásolhatja a m ködést. A legnagyobb veszélynek a trial szoftverek vannak kitéve, mivel a korlátozásuk egyszer módszerekkel megszüntethet , akár úgy, hogy visszaállítjuk a dátumot, vagy az adatok regisztrációs adatbázisból való törlésével újratelepítjük a programot. Az ilyen típusú programoknál könnyebb a crack alkalmazása is, mert egyértelm en be lehet határolni a védelem helyét, és könny módszerrel, minimális változtatásokkal lehet végleg teljes érték vé tenni a szoftvert. A shareware programok ennél lényegesen jobb

védelmet használnak, bár láttuk, hogy kell id ráfordítással ezeket a védelmeket saját magukkal lehet kijátszani (ugyanis tartalmazzák a kód el állításához szükséges algoritmust). Mindenesetre jobb az, hogy a letiltott menüpontokat, egyéb korlátozásokat egyszer módszerekkel nem szüntethet k meg, s bár gyakran nem járnak le, mint a trialware esetben, a programot nem lehet teljes kör en kihasználni a tiltások miatt. Az újratelepítés módszere sem ér semmit, mert a tiltásokat így sem lehet kijátszani. Egyértelm , hogy az ilyen programok teljes verzióvá tétele nagyobb szakértelmet igényel. Jellemz viszont az, hogy a shareware programokhoz sorozatszámot generáló programot írnak, így könnyen megkerülhet vé válik a védelem egy egyszer felhasználó számára is. Láttuk, hogy az ilyen generátorok írása nehezebb, mint egy crack létrehozása, így ezek a programok jelentik egyesek számára a legnagyobb kihívást. Általában elmondható,

hogy azok, akik a védelmeket elemzik, nem a programot magát akarják feltörni és használni, hanem maga a védelem és a sikerélmény hajtja ket. Az ebb l származó eredményt az egyszer felhasználó használja ki. Kódoláselméletb l tudjuk, hogy egy védelem akkor jó, ha a feltörése olyan hosszú id t vesz igénybe, hogy a védett adat értéke addigra elavulttá válik. Ez a koncepció a shareware és trialware programok esetében nem teljesül, s t jellemz en a szoftverek a következ verziójukban is ugyanazt a védelmet használják! Ahhoz, hogy egy kipróbálható verzió ténylegesen védett legyen, jó példát szolgáltattak a Demo programok. Megállapíthatjuk, hogy a jelenlegi módszerek a shareware és trialware programok védelmére, annyira keveset érnek, mintha a gyártók nem tör dnének azzal, hogy kik használják a programjaikat. Ezért mérlegelniük kellene, hogy esetleg több pénzt fektessenek egy-egy hibátlan demo verzió el állításába és a

teljes program terjesztésébe, mint hogy az illegálisan használt szoftverek miatt szenvedjenek el bevételkiesést. Ha ez nem megoldás, akkor sokkal jobb védelmi módszereket kellene kidolgozni, legalább olyan jót, ami kitart a következ verzió megjelenéséig, ahol mer ben más védelmi módszert kellene alkalmazni. Dolgozatom zárásaként megismerkedhettünk néhány, a múltban alkalmazott, védelemmel, majd felvázoltam ötleteket arra, hogyan lehetne olyan módszerekkel élni, mely megnehezítheti a programok feltörését, bár megállapítható, hogy hosszabb távon ezek sem nyújthatnak teljes megoldást. 56 9. Irodalomjegyzék és hivatkozások [1] http://www.jogiforumhu/publikaciok/13 Dr Marton Kálmán: A számítógépi programalkotások jogi védelme, 2005.0318 [2] http://www.jogiforumhu/publikaciok/127 Varga Balázs: Informatikai b ncselekmények, 2005.0317 [3] http://www.jogiforumhu/publikaciok/1910 Gross Balázs: A szoftverlicencszerz dések típusai,

20050317 [4] Agárdi Gábor: Gyakorlati assembly, LSI Oktatóközpont, [212], ISBN 9635771177 s Manual, [5] http://tinyurl.com/a7q76 IA-32 Intel(R) Architecture Software Developer 2005.0524 [6] http://www.jegerlehnerch/intel/indexhtml Intel assembly utasítás táblázat, 2005.0524 [7] Benk Tiborné, Benk László, Tóth Bertalan: Programozzunk C nyelven, ComputerBooks Kiadó Kft, 1996, [555], ISBN 9636181640 [8] http://tinyurl.com/9ts4z Windows32 API dokumentáció, 20050414 [9] http://www.jogiforumhu A jogi fórum az Interneten, 20050501 [10] Pálos - Jekler: A szoftverek szerz jogvédelme Magyarországon és a nemzetközi gyakorlatban. Forrás: Ügyészek lapja Belügyi Szemle Különszáma 1995 39 o [11] Bíró Kornélia: A szerz , a szoftver és a büntet jog. Forrás: Ügyészek lapja Szakmai Érdekképviseleti Folyóirat. 4/98 21 o [12] http://tinyurl.com/ch3f9 Cikk az illegális szoftverekr l Magyarországon, 2005.0601 [13] Pálos György: Business Software Alliance (BSA).

Forrás: Ügyészek Lapja Szakmai érdekképviseleti folyóirat 1/95: 28. o [14] http://www.serialsws Sorozatszám generátorok lel helye, 20050510 [15] http://www.cracksam Crack fájlok lel helye, 20050510 [16] http://www.rarlabcom A winrar program honlapja, 20050427 [17] http://www.nerocom A Nero Burning Rom internetes oldala, 20050501 57 10. Ábrajegyzék 1. ábra: Disassembler m ködés közben 13 2. ábra: Turbo Pascal nyomkövetés közben 14 3. ábra: A Turbo Debugger 15 4. ábra: Hexa editor 16 5. ábra: A regisztrációs adatbázis felépítése 19 6. ábra: A Nero program egyik sorozatszám generátora 21 7. ábra: Példa egy crack programra 21 8. ábra: Az Irfanview program regisztrációs ablaka 22 9. ábra: Sikertelen regisztráció 23 10. ábra: Sikeres regisztráció 23 11. ábra: A Mirc program indításkor 31 12. ábra: A Mirc regisztrációs ablaka 32 13. ábra: A program védelmének vizuális megjelenése 43 14. ábra: Lejárt program 43 58 11.

Melléklet 11.1 Fontosabb Microsoft Windows API függvények listája Fájlok írása, olvasása Ezek az általános hívások a fájlok írására, olvasására, általában bináris fájlokra ReadFile WriteFile Néhány függvény másfajta fájlelérésre: SetFilePointer GetSystemDirectory GetSystemDirectoryA (32 bites windowsban) Általános hívások *.ini fájlokra, vagy hasonló felépítés fájlokra: 16 bites rendszer alatt: 32 bites rendszer alatt: GetPrivateProfileString GetPrivateProfileInt WritePrivateProfileString WritePrivateProfileInt GetPrivateProfileStringA GetPrivateProfileIntA WritePrivateProfileStringA WritePrivateProfileIntA A regisztrációs adatbázis kezelésére használt függvények: Regisztrációs bejegyzés készítése vagy törlése: RegCreateKey RegDeleteKey RegCreateKeyA RegDeleteKeyA Egy megnyitott regisztrációs kulcsból való olvasás: RegQueryValue RegQueryValueA Regisztrációs kulcs zárása, illetve megnyitása: RegCloseKey

RegOpenKey RegCloseKeyA RegOpenKeyA Dialógus ablakok Egy szerkeszt mez tartalmának kiolvasása szöveg esetén: GetWindowText GetDlgItemText GetWindowTextA GetDlgItemTextA Egy szerkeszt mez tartalmának kiolvasása egész érték esetén: 59 GetDlgItemInt Üzenet ablak megnyitása: MessageBox MessageBoxA MessageBoxExA MessageBeep Más módon történ szövegmegjelenítés: SENDMESSAGE WSPRINTF Dátum és id kezelésére vonatkozó függvények Az id és a dátum lekérdezése: GetSystemTime GetLocalTime SystemTimeToFileTime Ablakok kezelése createwindow createwindowexa showwindow Adathordozó típus ellen rzés GetDriveType GetDriveTypeA A hívás visszatérési értékei: Érték 0 1 2 3 4 5 6 Jelentés Az adathordozó típusa nem megállapítható Root Mappa nem létezik Eltávolítható egység Merevlemez Távoli hálózati eszköz (Hálózat) Cd-Rom RamDisk GetLogicalDrives GetLogicalDrivesA GetLogicalDriveStrings GetLogicalDriveStringsA 60 Numerikus

adatbevitel GETWINDOWWORD GETWINDOWLONG Néhány hasznos függvény, amit szinte minden program használ hmemcpy bitblt 61 11.2 x86 Assembly utasítás készlet (Táblázat) 62 TRANSFER Name Comment Code Operation MOV XCHG Move (copy) Exchange MOV Dest,Source XCHG Op1,Op2 Dest:=Source Op1:=Op2 , Op2:=Op1 STC CLC CMC STD CLD STI CLI Set Carry Clear Carry Complement Carry Set Direction Clear Direction Set Interrupt Clear Interrupt STC CLC CMC STD CLD STI CLI CF:=1 CF:=0 CF:= ¬ CF DF:=1 (string op s downwards) DF:=0 (string op s upwards) IF:=1 IF:=0 PUSH PUSHF PUSHA Push onto stack Push flags Push all general registers Pop from stack Pop flags Pop all general registers PUSH Source PUSHF PUSHA DEC SP, [SP]:=Source O, D, I, T, S, Z, A, P, C 286+: also NT, IOPL AX, CX, DX, BX, SP, BP, SI, DI POP Dest POPF POPA Dest:=[SP], INC SP O, D, I, T, S, Z, A, P, C 286+: also NT, IOPL DI, SI, BP, SP, BX, DX, CX, AX ± CBW CWD CWDE Convert byte to word Convert word to

double Conv word extended double CBW CWD CWDE AX:=AL (signed) DX:AX:=AX (signed) EAX:=AX (signed) ± IN i Input IN Dest, Port OUT i Output OUT Port, Source POP POPF POPA 386 O D I T Flags S Z A P C 1 0 ± 1 0 1 0 ± ± ± ± ± ± ± ± ± ± ± ± ± Flags S Z ± ± ± ± A ± ± P ± ± C ± ± i for more information see instruction specifications AL/AX/EAX := byte/word/double of specified port Byte/word/double of specified port := AL/AX/EAX Flags: ±=affected by this instruction ?=undefined after this instruction ARITHMETIC Name Comment ADD Add ADC Add with Carry Code ADD Dest,Source ADC Dest,Source Operation Dest:=Dest+Source Dest:=Dest+Source+CF O D ± ± SUB SBB Subtract Subtract with borrow SUB Dest,Source SBB Dest,Source Dest:=Dest-Source Dest:=Dest-(Source+CF) ± ± ± ± ± ± ± ± ± ± ± ± DIV DIV DIV 386 Divide (unsigned) Divide (unsigned) Divide (unsigned) DIV Op DIV Op DIV Op Op=byte: AL:=AX / Op AH:=Rest

Op=word: AX:=DX:AX / Op DX:=Rest Op=doublew.: EAX:=EDX:EAX / Op EDX:=Rest ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IDIV IDIV IDIV 386 Signed Integer Divide Signed Integer Divide Signed Integer Divide IDIV Op IDIV Op IDIV Op Op=byte: AL:=AX / Op AH:=Rest Op=word: AX:=DX:AX / Op DX:=Rest Op=doublew.: EAX:=EDX:EAX / Op EDX:=Rest ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MUL MUL MUL 386 Multiply (unsigned) Multiply (unsigned) Multiply (unsigned) MUL Op MUL Op MUL Op Op=byte: AX:=AL*Op if AH=0 Op=word: DX:AX:=AX*Op if DX=0 Op=double: EDX:EAX:=EAX*Op if EDX=0 * ± ± ± ? ? ? ? ? ? ? ? ? ? ? ? ± ± ± IMUL i IMUL IMUL 386 Signed Integer Multiply Signed Integer Multiply Signed Integer Multiply IMUL Op IMUL Op IMUL Op Op=byte: AX:=AL*Op if AL sufficient * Op=word: DX:AX:=AX*Op if AX sufficient Op=double: EDX:EAX:=EAX*Op if EAX sufficient * ± ± ± ? ? ? ? ? ? ? ? ? ? ? ? ± ± ± INC DEC Increment Decrement INC Op DEC Op Op:=Op+1 (Carry not affected !)

Op:=Op-1 (Carry not affected !) ± ± ± ± ± ± ± ± ± ± CMP Compare CMP Op1,Op2 Op1-Op2 ± ± ± ± ± ± i ± ± ? ± ± i i ± ± ? ± ± ± SAL Shift arithmetic left ( SAL Op,Quantity SHL) SAR Shift arithmetic right SAR Op,Quantity RCL Rotate left through RCL Op,Quantity Carry RCR Rotate right through RCR Op,Quantity Carry ROL Rotate left ROL Op,Quantity ROR Rotate right ROR Op,Quantity i for more information see instruction specifications * I T i ± i i ± ± then CF:=0, OF:=0 else CF:=1, OF:=1 63 LOGIC Name Code Operation A P C NEG Op Op:=0-Op if Op=0 then CF:=0 else CF:=1 ± ± ± ± ± ± NOT AND OR XOR Negate (twocomplement) Invert each bit Logical and Logical or Logical exclusive or NOT Op AND Dest,Source OR Dest,Source XOR Dest,Source Op:=¬ Op (invert each bit) Dest:=Dest Source Dest:=DestSource Dest:=Dest (exor) Source 0 0 0 ± ± ± ± ± ± ? ? ? ± ± ± 0 0 0 SHL SHR Shift logical left ( SAL) Shift

logical right SHL Op,Quantity SHR Op,Quantity i i ± ± ± ± ? ? ± ± ± ± MISC Name NOP Comment No operation Code NOP Operation No operation Flags S Z A P C LEA Load effective address LEA Dest,Source Dest := address of Source INT Interrupt INT Nr interrupts current program, runs spec. intprogram NEG JUMPS (flags remain unchanged) Name Comment CALL Call subroutine Code CALL Proc JMP Jump JMP Dest JE JZ JCXZ JP JPE Jump if Equal Jump if Zero Jump if CX Zero Jump if Parity (Parity Even) Jump if Parity Even O O D D I T Flags S Z Comment I T 0 0 Operation Name RET Comment Return from subroutine Code RET Operation JE Dest JZ Dest JCXZ Dest JP Dest JPE Dest ( = JZ) ( = JE) JNE JNZ JECXZ JNP JPO Jump if not Equal Jump if not Zero Jump if ECX Zero Jump if no Parity (Parity Odd) Jump if Parity Odd JNE Dest JNZ Dest JECXZ Dest JNP Dest JPO Dest ( =JNZ) ( =JNE) 386 ( = JPO) ( JNP) JUMPS Unsigned (Cardinal) JA Jump if Above JAE Jump if

Above or Equal JA Dest JAE Dest (= JNBE) ( = JNB =JNC) JUMPS Signed (Integer) JG Jump if Greater JGE Jump if Greater or Equal JG Dest JGE Dest ( = JNLE) ( = JNL) JB JBE JNA JNAE JNB JNBE Jump if Below Jump if Below or Equal Jump if not Above Jump if not Above or Equal Jump if not Below Jump if not Below or Equal JB Dest JBE Dest JNA Dest JNAE Dest JNB Dest JNBE Dest ( =JNAE =JC) ( =JNA) ( = JBE) ( =JB =JC) (= JAE =JNC) ( =JA) JL JLE JNG JNGE JNL JNLE Jump if Less Jump if Less or Equal Jump if not Greater Jump if not Greater or Equal Jump if not Less Jump if not Less or Equal JL Dest JLE Dest JNG Dest JNGE Dest JNL Dest JNLE Dest ( = JNGE) ( = JNG) ( = JLE) ( = JL) (= JGE) ( JG) JC JNC Jump if Carry Jump if no Carry JC Dest JNC Dest JO JNO JS JNS Jump if Overflow Jump if no Overflow Jump if Sign (= negative) Jump if no Sign (= positive) JO Dest JNO Dest JS Dest JNS Dest ( = JPE) ( = JP) Status Flags (result of operations): C: Carry result of unsigned op. is too

large or below zero 1 = carry/borrow O: Overflow result of signed op. is too large or small 1 = overflow/underflow S: Sign sign of result. Reasonable for Integer only 1 = neg / 0 = pos Z: Zero result of operation is zero. 1 = zero A: Aux. carry similar to Carry but restricted to the low nibble only P: Parity 1 = result has even number of set bits Control Flags (how instructions are carried out): D: Direction 1 = string op s process down from high to low address I: Interrupt whether interrupts can occur. 1= enabled T: Trap single step for debugging 64