Välj en sida för handledning:
- Grunder — Information om C
- Verktyg
- Register
- Enkla instruktioner
- Exempel 1 — Initial verifiering av SC CDKey
- Exempel 2 — SC CDKey Shuffle
- Exempel 2b — SC CDKey Final Decode
- The Stack
- Stack Example
- Functions
- Example 3 — Storm.dll SStrChr
- Assembly Summary
- Maskinkod
- Exempel 4 — Smashing the Stack
- Cracking a Game
- Exempel 5 — Cracking a game
- Exempel 6 — Writing a keygen
- .dll Injection and Patching
- Memory Searching
- Exempel 7 — Att skriva ett fuskprogram för Starcraft (1.05)
- Exempel 7 Steg 1 — Visning av meddelanden
- Exempel 7 Steg 1b — Ovan, w/ func ptrs
- Exempel 7 Slutligt
- Exempel 8 — Att få IX86.dll-filer
- 16-bitars Assembly
- Exempel 9 — Keygen för ett 16-bitars spel
- Exempel 10 — Skriva en loader
Detta avsnitt kommer att gå igenom flera tekniker som används av crackers för att registrera spel/programvara. Jag nämner inte cd-cracks, eftersom jag inte vet hur man gör dem, utan jag nämner snarare attacker som i allmänhet är baserade på en nyckel eller registreringskod.
Gemensamma skydd
Det vanligaste skyddet, och det som diskuteras här, är när ett program kräver en registreringsnyckel för att låsas upp. Vanligtvis baseras nyckeln antingen på en slumpmässig registreringskod som tillhandahålls av programmet eller på det användarnamn som du anger.
Jag listar några definitioner här. Observera att dessa definitioner är mina och inte nödvändigtvis motsvarar de definitioner som andra använder. De är helt enkelt till för att göra det lättare att förstå detta och följande avsnitt:
- En registreringskod är en kod som genereras av ett program och som registreringsnyckeln härleds från eller kontrolleras mot.
- Ett användarnamn för registrering eller bara användarnamn är ett användarnamn som en användare anger. Registreringsnyckeln baseras på detta användarnamn.
- En registreringsnyckel är den nyckel som används för att låsa upp ett program. Den kan baseras på en registreringskod, på ett registreringsanvändarnamn eller på ingenting alls.
Finding the Spot
Det allra första exemplet går igenom Starcrafts CDKey-verifieringsalgoritm, men jag tillhandahöll algoritmen. Starcrafts är den enklaste typen av verifiering, nyckeln verifierar sig själv utan användarnamn eller kod. Frågan är hur man hittar algoritmen?
Det olyckliga svaret är att det varierar och att det i allmänhet inte är lätt.
Det första steget är naturligtvis att plocka isär programmet. Därefter måste man som cracker försöka hitta en svag punkt i programmet. Här är flera tekniker:
- Sök efter texten som uppmanar till att ange nyckeln
- Sök efter registreringskoden i minnet och ta reda på var den nås
- Ange en kod, låt den misslyckas och sök sedan i minnet efter den misslyckade koden
- Sök efter något unikt med registreringen (färger, text, dialogrutor etc.).
- Sök efter registernyckeln som lagrar nyckeln
- Sök efter en fil som lagrar registreringsinformation
- Sök efter felmeddelandet när en dålig nyckel anges
Den sista tekniken är den mest användbara, har jag funnit. Men att prova dem alla och prova allt annat som verkar passa spelet fungerar bäst. I exemplet i nästa avsnitt fann jag att det fungerade bra för spelet att söka efter texten som informerar användaren om att programvaran är oregistrerad, vilket du kommer att se senare. Det kan hända att jag gör ett andra exempel där jag sökte efter filen som lagrade nyckeln och var den skapades.
För att hitta Starcrafts CDKey-verifierare började jag med nätverkstrafiken, vid Winsock-funktionen (send() och recv()). Därifrån backtrackade jag för att hitta var paketet skickas som validerar Starcraft-nyckeln med Battle.net. Det var mycket arbete, men på den tiden lärde jag mig om Starcrafts nätverksaktivitet så det var mest en bieffekt av det jag redan gjorde. Om jag fortsätter att skriva dessa handledningar kan det hända att jag så småningom går in på så mycket detaljer, men jag har inga planer på det ännu.
Cracking the Game
När man väl har hittat rätt plats är det ofta väldigt enkelt att knäcka ett spel. Typiskt sett har ett program följande kod:
if(keyIsValid) unlock() else displayError()
Assembleringen för detta skulle se ut så här:
85 xx test keyIsValid, keyIsValid74 06 jz errore8 xx xx xx xx call unlockeb 06 jmp done error:e8 xx xx xx xx call displayError done:
Som diskuterats i avsnittet om maskinkod kan bytena till vänster vara maskinkodsbytena (jag gjorde dem snabbt från ett referensblad, så de kan eller inte kan vara exakt korrekta. Det här programmet kan ändras genom att ändra ett par bytes, vilket antingen kan tvinga koden att hoppa alltid eller hoppa aldrig.
För att tvinga koden att hoppa (vilket i det här fallet gör att nyckeln alltid är giltig) ersätts jz med en jmp (genom att ändra 74 till eb):
85 xx test keyIsValid, keyIsValideb 06 jmp errore8 xx xx xx xx call unlockeb 06 jmp done error:e8 xx xx xx xx call displayError done:
För att hindra koden från att hoppa (vilket i det här fallet gör att nyckeln alltid är giltig) ersätts jz med ett par nop-instruktioner:
85 xx test keyIsValid, keyIsValid90 nop90 nope8 xx xx xx xx call unlockeb 06 jmp done error:e8 xx xx xx xx call displayError done:
Företa lämpliga ändringar, kör spelet och skriv in någon kod. Det förväntade resultatet bör inträffa!
Nästa exempel kommer att visa detta på ett verkligt spel (på ett spel som jag av uppenbara skäl inte kommer att nämna här).
Skriva en keygen
Ett ännu bättre sätt än att knäcka ett spel är att skriva en keygen för det. Användaren anger sitt användarnamn eller sin registreringskod och keygen ger ut en giltig nyckel.
I allmänhet kräver detta att algoritmen är helt omvänd och förstådd. Sedan görs en kopia av den i C (eller vilket språk som helst) som ger samma resultat. Observera att de tre första exemplen i den här handledningen gör just detta: de förvandlar assemblerkoden tillbaka till C. Så den som faktiskt har följt dem borde vara i ett bra läge för att skriva en keygen, vilket kommer i en senare handledning.
Frågor
Känn dig fri att redigera det här avsnittet och ställa frågor, jag ska göra mitt bästa för att besvara dem. Men du kan behöva kontakta mig för att låta mig veta att en fråga finns.