Hogyan törjünk fel telepítõ programot?
avagy
"Az install script rejtelmei."

Készítette: Lukundoo [HPA]
e-mail:
Lukundoo@SoftHome.Net
web:
http://welcome.to/hpa

Tartalomjegyzék:
1. Mi iS az a telepítõ program?
2. Mi KELL hozzá?
3. HoGYAN kezdjünk hozzá?
4. HoGYAN készítsünk licensz szám generáló programot?

1. Mi iS az a telepítõ program?
Régen ha valaki programot írt, akkor kellett hozzá készíteni egy telepítõ programot is, ami a programot feltelepíti a felhasználó gépére, a szükséges beállításokat elvégzi, esetleg a beállítások elvégzése után újraindítja a gépet. Manapság már készen lehet "vásárolni" olyan programo(ka)t, ami(k) elvégzik a programozó helyett ezeket a dolgokat. Egyik legelterjedtebb ilyen program az "Install Shield" néven futó program, amit egyes programozási nyelvekhez alapból telepítõdik (pl. Borland Delphi III. Professional, Inprise termékek). Természetesen ezt a programot is le lehet tölteni az InterNET-rõl. Kezdettben még csak tömöríteni lehetett a programokat, és az IS feltelepítette ezeket  a tömörített file-okat. De az újabb verziókat már egy bonyolultabb script nyelvvel látták el, tehát a telepítõ programot is lehet programozni. Ezzel a programozási felülettel már egyszerû volt olyan telepítõ programot készíteni, ami csak adott jelszó esetén telepíti fel a file-okat.

2. Mi kell hozzá?
A mai feltörésünkhöz szükséges egy nagyon hasznos programocska, amivel ezeket a script-eket  lehet visszafejteni, a neve "Windows Installshield Decompiler",  és  a készítõje NatzGUL/Sirax. Továbbá szükségünk lesz egy programra, ami ezzel a módszerrel van védve. A választásom a "Performance '95 " nevû programra esett.

3. HoGYAN kezdjünk hozzá?
A  "Performance '95" nevü  program letölthetõ a következõ címrõl:
http://www.bonamisoftware.com
A file neve: p95vXXX.zip ahol az XXX az aktuális verziószámot mutatja. Miután kitömörítettük a file-okat, a következõ dolgokat találhatjuk meg:

DISK1.ID        Ez a lemezek számát jelenti, nem gyakran használják.
_SETUP.LIB      Ebben található az installálóhoz szükséges DLL-ek.
DATA.Z          Ebben vannak betömörítve a file-ok.
UNINST.EXE      Ezzel lehet UNInstallálni a telepített file-okat.
SETUP.EXE       Ez a telepítõ program.
SETUP.ISS       Ez tök felesleges!
SETUP.PKG       Ebben vannak eltárolva a tömörített file-ok helye.
LICENSE.TXT     Licensz szöveg, nem kell!
SETUP.INS       Ez kell nekünk! Ebben van a SCRIPT program!
SUPP95.DLL      Ez nem tudom miért kell???
README.TXT      Mielött telepítjük, olvassuk el. Nem kell!
_SETUP.DLL      A telepítõ programnak kell.

Miután elindítottuk a telepítõ programot, bejön pár ablak, ami értesít minket arról, hogy ez a program SHAREWARE, és errõl ne feledkezzünk meg. Ezután a "Next" gombra nyomva bejön a licenszfeltételek ablaka, ez se érdekel senkit! Nyomjunk rá az "Accept" gombra. Ekkor bejön egy ablak, ahova be kell írnunk a nevünket, én azt írtam be, hogy:

Lukundoo,[HPA]

Miután ezzel is megvolnánk, akkor jön a számunkra érdekes ablak, mert a következõ ablakban bizony a licensz számunk beírását kéri. Pufff!!! Hát azt így fejbõl senkise tudja ugyebár. Jegyezzük meg azt a szót, ami az ablak fejlécében van:

Enter License Information

Ez majd késöbb kell nekünk!  Most  inkább lépjünk ki a programból, és indítsuk el a WISDEC nevü programot. A WISDEC program elindulása után kattintsunk rá  a  "File"  menü "Open Script File"  menüpontjára,  és keressük meg azt a helyet, ahova kitömörítettük a .ZIP állományt.  Ha megvagyunk, akkor felajánlja  nekünk a "Setup.ins" nevü állományt. Ha megnyitjuk, akkor a program beolvassa a file-t a memóriába. Ezután rá kell kattintani a "Decompile" menü, "Start..." menüpontjára, és a program szépen visszafejti nekünk a SCRIPT-et. Ha készvan vele, akkor kapunk valami ilyesmit:

0000020A: 0013   StrVar[000F] = "Copyright (c) BonAmi Software.......
0000025D: 0021   NumVar[000C] = 00000000
00000267: 0002   Disable (0000000C)
0000026E: 00B5   Call Function_0000_[LABEL_0045]  ()
00000276: 0146   InstallationInfo ("BonAmi Software","Performan......
000002AF: 0124   StrVar[001E] = SRCDIR + "supp95.dll"

<LABEL_0001> REF: 000004C5
  |
000002D0: 0002   Disable (00000032)

Ez nekünk így tökéletes. Most már nincs más hátra, rá kell keresnünk arra hogy "Enter License Information".Kattintsunk rá az StrRef gombra, és ekkor megkapjuk a sztring referenciákat. Meg is találjuk, és rákattintva odavisz minket, ahol ezt használja a program:

000004E6: 003B   SetDialogTitle (00000005,"Enter License Information")
00000509: 0013   StrVar[000F] = ""

Itt vagyunk, annál  a  résznél, ahol a program ellenõrzi, hogy milyen számot ütöttünk be. Most már csak ki kell elemezni,hogy mit is csinála progi itt: elõször lássuk a teljes programot, aki már foglalkozott egy kicsit is a programozással, annak gyerekjáték lesz ezt megfejteni. A sor alatt fogom magyarázni mindig, hogy mit csinál az aktuális sor:

000004E6: 003B   SetDialogTitle (00000005,"Enter License Information")
Megadjuk, hogy mi legyen a felirata a dialogus ablaknak.

00000509: 0013   StrVar[000F] = ""
Ez egy üres string.

00000511: 0124   StrVar[000F] = StrVar[000F] + "Please enter your license number below."
Ezeket a sztringváltozókat feltöltjük szöveggel.

0000054D: 0124   StrVar[000F] = StrVar[000F] + "If you have not yet purchased a license and you would like"
0000059A: 0124   StrVar[0020] = StrVar[000F] + " to evaluate the software, please use: "
000005CC: 0124   StrVar[000F] = StrVar[0020] + "P95-EVAL-LICENSE"
00000612: 0128   IF (AskText (StrVar[000F],"P95-EVAL-LICENSE",StrVar[001A]) = 0000000C) THEN
00000632: 002C        Goto (LABEL_0005)
00000633: 0000   ENDIF

Itt egy ellenörzés  van, hogyha  a  beütött  szám "P95-EVAL-LICENSE", akkor ugorjon a LABEL_005 -re. Ez minket nem érdekel!

0000063F: 003B   SetDialogTitle (00000005,"Enter Information")
Megadjuk, hogy mi legyen a felirata a dialogus ablaknak.

0000065A: 0021   NumVar[0008] = 00000001
00000664: 0021   NumVar[0007] = 00000001

Ennek a két változónak egyes értéket adunk.

0000066E: 00DB   StrToUpper (StrVar[001B],StrVar[001A])
Az StrVar[001B]-t betûit, nagybetûkké alakítja.

00000676: 0013   StrVar[001A] = StrVar[001B]
0000068B: 0128   IF (GetByte (StrVar[001A],00000000) != 00000050) THEN
000006AB: 0021        NumVar[0007] = 00000000
000006AC: 0000   ENDIF

Itt jön egy érdekes rész: hogyha az StrVar[001A] nulladik karaktere nem egyenlö "P"-vel, akkor a NumVar[0007] értéke 0 lesz.

000006CA: 0128   IF (GetByte (StrVar[001A],00000001) != 00000039) THEN
000006EA: 0021        NumVar[0007] = 00000000
000006EB: 0000   ENDIF

Ugyan az mint az elõzõ, csak itt az elsõ betûnek "9"-nek kell lennie.

00000709: 0128   IF (GetByte (StrVar[001A],00000002) != 00000035) THEN
00000729: 0021        NumVar[0007] = 00000000
0000072A: 0000   ENDIF

Második betûnek "5"-nek kell lennie.

00000748: 0128   IF (GetByte (StrVar[001A],00000003) != 0000002D) THEN
00000768: 0021        NumVar[0007] = 00000000
00000769: 0000   ENDIF

Harmadik betûnek "-"-nek kell lennie.

00000787: 0128   IF (GetByte (StrVar[001A],00000004) != 00000056) THEN
000007A7: 0021        NumVar[0007] = 00000000
000007A8: 0000   ENDIF

Negyedik betûnek "V"-nek kell lennie.

000007C6: 0128   IF (GetByte (StrVar[001A],00000006) != 0000002E) THEN
000007E6: 0021        NumVar[0007] = 00000000
000007E7: 0000   ENDIF

A hatodik betûnek "."-nak kell lennie.

00000805: 0128   IF (GetByte (StrVar[001A],00000009) != 0000002D) THEN
00000825: 0021        NumVar[0007] = 00000000
00000826: 0000   ENDIF

A kilencedik betûnek "-"-nek kell lennie.

00000837: 007A   NumVar[000A] = GetByte (StrVar[001A],0000000A)
00000844: 0128   NumVar[000E] = NumVar[000A] < 00000030
00000856: 0128   NumVar[000F] = NumVar[000A] > 00000039
00000873: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
00000881: 0021        NumVar[0007] = 00000000
00000882: 0000   ENDIF

Itt megnézi, hogy a tizedik betû értéke  a 0 és a 9 között  van e. Ha szám, akkor elfogadja, ha nem, akkor hiba van!

00000893: 007A   NumVar[000A] = GetByte (StrVar[001A],0000000B)
000008A0: 0128   NumVar[000E] = NumVar[000A] < 00000030
000008B2: 0128   NumVar[000F] = NumVar[000A] > 00000039
000008CF: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
000008DD: 0021        NumVar[0007] = 00000000
000008DE: 0000   ENDIF

Ugyan az mint az elõbb, csak most a tizenegyedik betût ellenõrzi.

000008EF: 007A   NumVar[000A] = GetByte (StrVar[001A],0000000C)
000008FC: 0128   NumVar[000E] = NumVar[000A] < 00000030
0000090E: 0128   NumVar[000F] = NumVar[000A] > 00000039
0000092B: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
00000939: 0021        NumVar[0007] = 00000000
0000093A: 0000   ENDIF

Ugyan az mint az elõbb ,csak most a tizenkettedik betût ellenõrzi.

0000094B: 007A   NumVar[000A] = GetByte (StrVar[001A],0000000D)
00000958: 0128   NumVar[000E] = NumVar[000A] < 00000030
0000096A: 0128   NumVar[000F] = NumVar[000A] > 00000039
00000987: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
00000995: 0021        NumVar[0007] = 00000000
00000996: 0000   ENDIF

Ugyan az mint az elõbb ,csak most a tizenharmadik betût ellenõrzi.

000009A7: 007A   NumVar[000A] = GetByte (StrVar[001A],0000000E)
000009B4: 0128   NumVar[000E] = NumVar[000A] < 00000030
000009C6: 0128   NumVar[000F] = NumVar[000A] > 00000039
000009E3: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
000009F1: 0021        NumVar[0007] = 00000000
000009F2: 0000   ENDIF

Ugyan az mint az elõbb ,csak most a tizennegyedik betût ellenõrzi.

00000A03: 007A   NumVar[000A] = GetByte (StrVar[001A],0000000F)
00000A10: 0128   NumVar[000E] = NumVar[000A] < 00000030
00000A22: 0128   NumVar[000F] = NumVar[000A] > 00000039
00000A3F: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
00000A4D: 0021        NumVar[0007] = 00000000
00000A4E: 0000   ENDIF

Ugyan az mint az elöbb ,csak most a tizenötödik betüt ellenörzi.

00000A5F: 007A   NumVar[000A] = GetByte (StrVar[001A],00000010)
00000A6C: 0128   NumVar[000E] = NumVar[000A] < 00000030
00000A7E: 0128   NumVar[000F] = NumVar[000A] > 00000039
00000A9B: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
00000AA9: 0021        NumVar[0007] = 00000000
00000AAA: 0000   ENDIF

Ugyan az mint az elöbb ,csak most a tizenhatodik betüt ellenörzi.

00000ABB: 002F   NumVar[000B] = StrLength (StrVar[001A])
00000AE8: 0128   IF (StrCompare (StrVar[001A],"P95-EVAL-LICENSE") = 00000000) THEN
00000B08: 002C        Goto (LABEL_002E)
00000B09: 0000   ENDIF

Itt mégegyszer ellenörzi, hogy "P95-EVAL-LICENSE"-t ütöttünk-e be.

00000B15: 0128   NumVar[000E] = NumVar[0007] = 00000000
Nem érdekes.
00000B27: 0128   NumVar[000F] = NumVar[000B] != 00000011
Nem érdekes.

00000B44: 0022   IF (NumVar[000E] || NumVar[000F] != 00000000) THEN
Hogyha a NumVar[000E] vagy a NumVar[000F] értéke 0 akkor....

00000B52: 0124   Sprintf (StrVar[0020],"Invalid license number.  Please verify the number on ","your Registration Card and enter it exactly as shown.")
Kiír egy hibaüzenetet.

00000BC7: 002A        MessageBox (StrVar[0020],SEVERE)
Hibaüzenete ablaka.

00000BE6: 0128        IF (NumVar[000C] +  >= 00000003) THEN
Hogyha a gomb értéke >=3 akkor...

00000C06: 002B             Exit ()
...kilép,

00000C08: 0000        ELSE
Ha nem akkor

00000C11: 002C             Goto (LABEL_0008)
Vissza ugrik az elejére.

Most már tudjuk hogy  milyen a  felépítése a szériaszámnak. Most  már csak az a dolgunk, hogy szériaszámot generáljunk. Ime hogyan épül fel a szériaszám:

P95-V?.??-XXXXXXX

Ahol kérdõjelek vannak, ott nem tudjuk még, hogy mi kell oda. De ha egy kicsit jobban odafigyelünk, akkor láthatjuk, hogy oda az éppen aktuális verziószám jön.  Az "X"-ek  helyére pedig bármilyen szám kerülhet. Most már  csinálhatunk  tetszés  szerint  licensz számokat:

P95-V2.01-6661666
P95-V2.01-2222222
P95-V2.01-1999121
P95-V2.01-1111888
P95-V2.01-6969696

De sokkal egyszerübb, hogyha  készítünk  egy  programot , ami generál nekünk szériaszámot.

 4. HoGYAN készítsünk licensz szám generáló programot?
Tudnunk kell mielõtt generálunk számokat, hogy milyen verziójú a program. Továbbá illik  megkérdezni a felhasználót, hogy hány számot szeretne... :) Én a programot Turbo Pascal nyelvben írtam meg, hogyha valakinek sok ideje van, akkor meg lehet írni assembly nyelven is. Ime a forráskód:

Var S,T,Version,Numb:String;
    I,Counter:Byte;
    I2,Code:Word;

Function IntToStr(I:Longint):String; (*Integer -t sztringé! *)
Var S: string[11];
Begin
     Str(I,S);
     IntToStr:=S;
End;

Function ReadKey:Char;Assembler; (*Karaktert várunk*)
Asm
   Mov ah,00h
   Int 16h
End;

Begin
     WriteLn('  yyy.    yyyy.   yyyyyyg.         ,yyyyyy     ');
     WriteLn(' jQQQQ    QQQQQ   QQQQQQQQQy       QQQQQQQg    ');
     WriteLn(' jQQQQ    QQQQQ   QQQQW"WQQQQg    pQQQWQQQQ    ');
     WriteLn(' jQQQQyy_yQQQQQ   QQQQF  jQQQQ   jQQQW  QQQg   ');
     WriteLn(' jQQQQQQQQQQQQQ   QQQQ#_jQQQQF   QQQQ____QQQf  ');
     WriteLn(' jQQQQQWQQQQQQQ   QQQQQQQQQQP   #QQQQQQQQQQQQ  ');
     WriteLn(' jQQQQf   jQQQQ   QQQQQWW@"`   jQQQQQQQQQQQQQg ');
     WriteLn(' jQQQQ#   jQQQQ   QQQQQ       jQQQQf    `"QQQQc');
     WriteLn(' "@@@@@   +@@@@   PPPVV       VVVVP       VVVVP');
     WriteLn('      HunGaRiaN PiraTeS AlliancE Present''s');
     WriteLn('Performance ''95 regkey generator by Lukundoo [HPA]');
     Randomize;
     WriteLn;
     Write('þ enter Performance 95 version number (2.01 or 3.01):');

     ReadLn(Version);
     If ((Length(Version)<1) Or (Length(Version)>4)) Then
     Begin (*Ha kissebb mint egy betü, vagy nagyobb mint 4 betü..*)
          WriteLn('þ min 1. and max 4. character!');
          Halt;
     End;
     Write('How many number would You like:');
     ReadLn(Numb); (*Hány szériaszámot akarunk?*)
     Val(Numb,I2,Code);
     if code <> 0 then
     Begin (*Ha nem számot ad meg...*)
          Writeln('þ are You stupid, or what??');
          Halt;
     End;
     WriteLn;
     Counter:=0;
     For Code:=1 To I2 Do (*Hozzákezdünk a gyártáshoz*)
     Begin
          If Counter>20 Then (*Ha 20-at kiírtunk, akkor megállunk*)
          Begin
               Counter:=0;
               WriteLn('þ press any key to countinued...');
               ReadKey;
          End;
          Write(Code,'.) P95-V',Version,'-');
          For i:=1 To 7 Do
          Begin
               Write(Chr(48+(Random(10)))); (*Csak számot írunk ki*)
          End;
          Writeln;
          Inc(Counter);
     End;
     WriteLn('þ done!');
End.

5. ENNYiT mára!
Remélem hogy érthetõ volt ez a kis bemutató, és mindenki gerjedezik egy jó kis installscript törésre. Ha úgyérzed, hogy kedven van a programok feltöréséhez, akkor írj e-mail-t nekem, és felveszünk az HPA trial member-ének !  Köszönet azért, hogy  elolvastad ezt a kis doksit, és  visszajelzel,  hogyha valamit nem értesz belõle.


Lukundoo [HPA]
1999. jan. 21.