Smashing Commercial Protection I : SoftSentry 2.11
        thinked & written by (R)ipLey 25/06/99

--- DISCLAIMER ---------------------------------------------------------------
 io mi pento e mi dolgo con tutto il cuore perke' ho peccato
 per mia kolpa, mia kolpa, mia grandissima kolpa
 e suppliko la beata sempre "vergine" corte di pregare x me
 il signor Giudice di non kondannarmi :)

 Signor Giudice perdonali xche' non sanno quello ke fanno!!! :))

 Naturalmente non mi assumo nessuna responsabilita' x cio' ke farete
 con le informazioni ke daro' nel presente tut.
------------------------------------------------------------------------------

Questo Tutorial (e' il secondo che scrivo ma il primo trattava di Backdoors,
quindi tendeva + sull' hacking ) sara' (spero) il primo di una serie il cui
scopo e' quello di eliminare qualcosa che rende noiosa quella che per noi
e' una appassionante sfida.
Infatti per come la vedo io il cracking e' una sfida fra il cracker e il
programmatore ( e ke vinca il migliore :) e queste kzz di protezioni
commerciali rendono questa sfida alquanto noiosa :

il gusto sta nel cercare di capire, studiando il disassemblato, quale sega
mentale il programmatore si e' sognato per farci perdere tempo (perke' mi
sembra scontato ke primo o poi qualkuno riuscira' a uscirne vincitore)...
detto questo mi sembra inutile dire ke non c'e' assolutamente nessun gusto a
crackare 300 programmi tutti con la stessa protezione del kazzo, o no ?
(Non penso ke contarsi quanti crack si sono realizzati per poi vantarsi di
essere il nuovo +ORC sia un atteggiamento degno di stima.

CORO : lo dici solo perke' i tuoi crack li puoi contare sulle dita
       di una mano!!!! :))))
)

Possibile che i programmatori non si rendano conto di quanto inutili siano
queste soluzioni preconfezionate ?!?!?!?

Principalmente penso che questa tendenza sia dovuta al rincaro della cocaina
necessaria (a kili) ai programmatori per studiare un modo creativo di giocare
con noi (o noi di giocare con loro? :).
A parte gli scherzi cmq non riesco a capire con quale coraggio i programmatori
paghino la licenza di utilizzo del softSentry che protegge i programmi in un
modo kosi' squallido ke quasi mi viene da piangere ;-(.

Penso di aver esaurito le kazzate ke volevo dire (tanto lo so ke le avete
saltate :) e possiamo kominciare kon le kose serie.

----- SKEDA INFORMATIVA ------------------------------------------------------
Nome Programma    : SoftSENTRY v2.11

Software House    : 20/20 Software

URL               : www.twenty.com

Tipo              : applica una protezione configurabile dall'utente
                    (programmatore) direttamente sull'eseguibile del
                    programma.

Segni Particolare : Troppo stronzo x essere vero :D

-----------------------------------------------------------------------------

Un bel giorno giocando al "piccolo cracker" con un programmino shareware
(Grass Hopper v1.0.5 della Santrim Software - un browser in VB6) sbagliando
a modificare un locazione di memoria ho visto apparirmi una dialog ad
avvertirmi :

"softSENTRY - Failed to run!"

o qualcosa di simile... questo nome SoftSentry mi suonava vagamente conosciuto
cosi' mi sono messo a cercare dove ne avevo letto qualcosa.
Be', sulle "Cracker's N0tes" di TORN@DO  c'e' una piccola sessione riguardante
questo ignobile programma :

Nella versione 2.007 del SoftSentry bastava cercare le due call (sempre le stesse)
che si occupano di caricare le risorse e caricare il programma e spostarle(con le
opportune modifiche di rilocazione) all'inizio del programma al posto dell'entry
point standard del softSentry... ed il gioco e' fatto!!! :)

Ora, verificato che la versione usata dal "mio" programma era leggermente diversa
ho prima trovato il modo di convertire quanto appreso dalle "Cracker's N0tes"
per adattarlo al mio caso e poi ho scaricato dal sito della "20/20 Software" la
versione trial del loro "interessantissimo" prodotto per vedere quanto standard
fosse la loro soluzione automatica di protezione del software...

Vi diro' che una volta appreso il meccanismo vi bastera' l'HIEW  e un PEBrowse
per crackare tutti i programmi protetti da questo pacchetto ke a mio avviso e'
una vera e propria truffa...
Usare il SoftIce per crackare questa protezione sarebbe come usare un martello
pneumatico per aprire una nocciolina... una vera e propria follia!!! :).

Naturalmente la prima cosa che mi e' venuta in mente e' stata di vedere se per
proteggere la versione trial del loro ignobile programma avessero scelto di
usare il loro stesso "infallibile" sistema automatizzato...
Ebbene per la serie "La Follia Umana e' Infinita" e prodotto da "Il Modo e' Bello
Perche' e' Vario"-Production... si! hanno usato il loro sistema del kazzo.
A questo punto le cose sono due :

1. O dopo un "attento" esame hanno giudicato il loro sistema infallibile...
2. Oppure hanno una considerazione cosi' bassa dei cracker da considerarci
   dei ritardati mentali che mettono breakpoint a kzz e modificano il codice
   assembler delle applicazioni usando i piedi.

Probabilmente entrambe le cose!!!

--- 1. Know Your Enemy (Rage Against The Machine) ----------------------------
Prima di tutto come facciamo a riconoscere se il programma che abbiamo fra le
mani e' protetto con il SoftSentry ???
Lo possiamo capire in diversi modi :

1.Section Headers doppi
  Oltre a quelli "standard" (.text , .data , .rdata etc...) ce ne saranno
  altri ancora + "standard" (hehehe) come _data, _idata, _rsrc, e _reloc ma
  sopratutto una sezione chiamata 20/20tm (vi dice niente?:)

2.Standard Resources
  Nelle risorse troveremo una sezione "LWJDATA" e fra le Dialog una chiamata
  SENTRYABORTDLG

3.Hiew - "Import Strange Data" Warning
  Quando aprite l'eseguibile con l'HIEW questo ci da il suddetto warning.

4.Standard Entry Point OpCodes
  L'Entry Point del programma contiene sempre le stesse istruzioni :

  55            push    ebp
  8BEC          mov     ebp, esp
  83EC64        sub     esp, 64
  53            push    ebx
  56            push    esi
  57            push    edi
  E950000000    jmp     .xxxxxxxxx

  Impossibile sbagliare :))

Non vi Basta ?!?!??!?!?!?!?!?

La protezione consiste nell'aggiunta della sezioni standard del softSENTRY che
effettuano il controllo sulla scadenza del Trial Mode e sulla lettura del
codice seriale in caso di errore termina il processo dopo averci avvertito
che dobbiamo comprare il programma altrimenti va ha caricare il programma vero
e proprio...
Ed e' questa la parte che ci interessa.
Tracciando con il SoftIce (solo la prima volta x capire il funzionamento della
protezione:) quello che avviene dopo aver premuto il tasto "Try" sulla dialog
di registrazione arriveremo ad una call che avviera' il programma.
Questa funzione si presentera' cosi (sempre!!! non si puo' sbagliare) :

          56                    push    esi
          57                    push    edi
          8BF2                  mov     esi, edx
          8B7C240C              mov     edi, [esp+0C] ; 00400000 (ImageBase?)  
          8B5102                mov     edx, [ecx+02] ; MagicNumber1
          335106                xor     edx, [ecx+06] ; MagicNumber2
          33510A                xor     edx, [ecx+0A] ; MagicNumber3
          03FA                  add     edi, edx
          33D2                  xor     edx, edx
 loop1 :  8B4106                mov     eax, [ecx+06] ; MagicNumber2
          42                    inc     edx
          314497FC              xor     [edx*4+edi-04], eax
          42                    inc     edx
          8B410A                mov     eax, [ecx+0A] ; MagicNumber3
          314497FC              xor     [edx*4+edi-04], eax
          83FA14                cmp     edx, 14
          7CEB                  jl      loop1
          8B0E                  mov     ecx, [esi]
          E85F320000            call    xxxxxxxx
          C70600000000          mov     dword ptr [esi], 00000000
          66833DB8E1400000      cmp     word ptr [0040E1B8], 0000
          740C                  jz      error1       
          66833DC0E1400000      cmp     word ptr [0040E1C0], 0000
          7402                  jz      error1       
          FFD7                  call    edi
error1 :  6A00                  push    00
          68xxxxxxxx            push    xxxxxxxx
          68xxxxxxxx            push    xxxxxxxx
          6A00                  push    00
          FF15xxxxxxxx          call    [User32!MessageBoxA]
          5F                    pop     edi
          5E                    pop     esi
          C20400                ret     0004

con le "x" ho indicato cio' che variera' fra un eseguibile ed un altro...
il resto sara' sempre uguale :)))
Il funzionamento e' piuttosto semplice e se provate a tracciarla sicuramente
non impiegherete + di 30 millisecondi x capire cosa fa'...
"decripta" (e' una parola grossa x il caso in questione ma + o - e' quello che
fa' :) le prime 40 dword del programma vero e proprio e poi lo esegue con
la "call edi".
Ora ci tocca capire da dove ricava le dword che usa per il decriptaggio.

Innanzitutto va detto che edi con l'istruzione :
        mov     edi, [esp+0C]
diventa sempre 0x00400000 e questo penso sia il valore dell'imageBase dello
eseguibile in quanto era sempre lo stesso per tutti i programmi protetti con
softSENTRY che ho visto (forse per le DLL sara' diverso)

Mentre e' + interessante capire da dove vengono le 3 dword usate nello snippet :
        mov     edx, [ecx+02]
        xor     edx, [ecx+06]
        xor     edx, [ecx+0A]
e successivamente :
        mov     eax, [ecx+06]
        ....
        mov     eax, [ecx+0A]

Per capire da dove vengono dobbiamo innanzitutto capire che cosa indica e da
dove viene il valore associato ad ecx quindi saliamo di 1 livello:

        8B4DB8          mov     ecx, [ebp-48]       ;<----- da qui ricava ecx
        E834000000      call    decrypt_and_run     ;la "nostra" funzione :)

con un bel breakpoint sulla memoria vediamo chi e' che ci scrive quel
valore in memoria...
ci sono solo 2 o 3 punti prima della "nostra" funzione in cui quell'area di
memoria viene modificata ma a noi interessa solo l'istruzione che ci inserisce
il valore "giusto", quello che avevamo trovato in ecx al momento del
decryptaggio...

Risalendo arriveremo a trovare un funzione del programma che ricava proprio
il valore che stavamo cercando tramite delle chiamate al kernel...

        ....
        68xxxxxxxx      push    xxxxxxxx          ; lpType-->FindResourceA
        50              push    eax               ; lpName-->FindResourceA
        8B3Dxxxxxxxx    mov     edi, [Kernel32!GetModuleHandleA]
        6A00            push    00                ; lpModuleName-->GetModuleHandleA
        FFD7            call    edi
        50              push    eax               ; hModule-->FindResourceA
        FF15xxxxxxxx    call    [Kernel32!FindResourceA]
        85C0            test    eax, eax
        7421            jz      error1
        50              push    eax               ; hResInfo-->LoadResource
        6A00            push    00                ; lpModuleName-->GetModuleHandleA
        FFD7            call    edi
        50              push    eax               ; hModule-->LoadResource
        FF15xxxxxxxx    call    [Kernel32!LoadResource]
        8906            mov     [esi], eax
        85C0            test    eax, eax
        740F            jz      error1
        50              push    eax               ; hResData-->LoackResource
        FF15xxxxxxxx    call    [Kernel32!LockResource]
        8BF0            mov     esi, eax          ; esi=pointer to data
        85F6            test    esi, esi
        7515            jnz     ok1
        EB04            jmp     error2
error1: 8B742408        mov     esi, [esp+08]      ; error in
error2: BAxxxxxxxx      mov     edx, xxxxxxxx      ; loading
        B9xxxxxxxx      mov     ecx, xxxxxxxx      ; resources
        E827000000      call    show_message_box
   ok1: 8BC6            mov     eax, esi
        5F              pop     edi
        5E              pop     esi
        83C404          add     esp, 04
        C3              ret

/= GetModuleHandle =========================================================\
|                                                                           |
|    HMODULE GetModuleHandle(                                               |
|        LPCTSTR lpModuleName      // puntatore al nome del modulo di cui   |
|                                  // vogliamo l'handle.                    |
|    );                                                                     |
|                                                                           |
|    ritorna l'handle del modulo specificato da "lpModuleName" o se         |
|    "lpModuleName" e' NULL quello del file usato x creare il processo      |
|    chiamante (questo e' il nostro caso:)                                  |
\---------------------------------------------------------------------------/

/= FindResource ============================================================\
|                                                                           |
|    HRSRC FindResource (                                                   |
|        HMODULE hModule,     // handle del modulo                          |
|        LPCTSTR lpName,      // puntatore al nome della risorsa            |
|        LPCTSTR lpType       // puntatore al nome del tipo di risorsa      |
|    );                                                                     |
|                                                                           |
|    localizza una risorsa con il nome e il tipo specificato nel modulo     |
|    specificato. (se la parte alta di lpName e' 0 la parte bassa sara'     |
|    l'identificativo intero della risorsa - questo e' in nostro caso :))   |
\---------------------------------------------------------------------------/

/= LoadResource ============================================================\
|                                                                           |
|    HGLOBAL LoadResource (                                                 |
|        HMODULE hModule,     // handle del modulo                          |
|        HRSRC   hResInfo     // handle della risorsa                       |
|    );                                                                     |
|                                                                           |
|    carica la risorsa specificata nella Global Memory.                     |
\---------------------------------------------------------------------------/

/= LockResource ============================================================\
|                                                                           |
|    LPVOID LoadResource (                                                  |
|        HGLOBAL hResData     // valore ritornato dalla LoadResource        |
|    );                                                                     |
|                                                                           |
|    bocca la risorsa specificata in memoria.                               |
|    Ritorna un puntatore al primo byte della risorsa in caso di successo,  |
|    altrimenti NULL.                                                       |
\---------------------------------------------------------------------------/


studiando un po' il codice (non ci vuole poi molto) arriveremo a capire che
non fa altro che caricare una risorsa dall'eseguibile stesso e il valore in
ecx e' l'indirizzo di memoria dove la risorsa e' stata caricata...
Ma le sorprese non sono finite perke' la risorsa in questione fa parte della
sezione "LWJDATA" che vi avevo fatto notare come caratteristica del softSENTRY
ed e' precisamente quella con ID = 103 (67hex).

Ora mai sappiamo abbastanza di questo ignobile programma e possiamo passare
al contrattacco :))

--- 2. Kill You (Korn - Life is Peachy) ---------------------------------------
Io esporro' il mio modo di agire poi voi siete liberi di utilizzare i tools ke
+ vi piacciono :)))

Ingredienti :
  1 Kg    di  PEBrowse Professional 1.2.1.0
  200 g   di  HIEW 6.04
  5   g   di  Ganja
  1 pacco di  Camel da 10
  1 pacco di  Smoking Red
  1 riduzione discoteca
  1 birra gelata (a DuDemon 4 me)

Gli ultimi 5 ingredienti servono a rendere il lavoro meno noioso :))

Aprite l'eseguibile col PEBrowse (e la birra anche...:) nelle risorse cercate
LWJDATA e sotto LWJDATA la risorsa con ID=103.
Chiedete gentilmente al PEBrowse se ve la puo' dumpare e se acconsente
(il caldo nuoce gravemente alla mia salute psichica) provvedete prima ad
allineare i byte (ricordate? ecx+02...ecx+06...ecx+0A... quindi spostatevi 2
byte a destra) e convertite il tutto in dword :

Ecco a voi i 3 numeri magici (li chiameremo MagicNumber1, 2 e 3 :) che vengono
usati per decryptare il codice.
Segnateli.... vi serviranno :)

Ora salutiamo il PEBrowse il quale non ci servira' + (ccccciiiiiaaaaaoooooo:))
E chiamiamo il nostro fido HIEW (arf... arf... :)

Posizioniamoci sull'entry point e...
riscriviamolo in modo ke proceda direttamente al decriptaggio ed esecuzione del
programma vero e proprio saltando a pie' pari tutto il codice del softSENTRY

        BF00004000   mov     edi, 00400000
        BAxxxxxxxx   mov     edx, MagicNumber1
        B8yyyyyyyy   mov     eax, MagicNumber2
        BBzzzzzzzz   mov     ebx, MagicNumber3
        33D0         xor     edx, eax
        33D3         xor     edx, ebx
        03FA         add     edi, edx         
        33D2         xor     edx, edx         
loop1 : 42           inc     edx
        314497FC     xor     [edx*4+edi-04], eax
        42           inc     edx
        315C97FC     xor     [edx*4+edi-04], ebx
        83FA14       cmp     edx, 14
        7CF1         jl      loop1
        FFD7         call    edi

al posto di MagicNumber1,2 e 3 (e quindi delle "x", "y" e "z") inserite i
numeri "magici" trovati con il PEBrowse e poi .....

Basta, questo e' tutto il programma funzionera' fregandosene altamente che
il trial sia terminato o meno.
Possiamo inoltre essere sicuri che il programma funzionera' come se fosse
registrato in quanto e' totalmente all'oscuro della protezione perke' aggiunta
in seguito ( questo gioca a nostro favore, no? )

--- 3. Last Exit (Perl Jam - Vitalogy) ---------------------------------------

Bibliografia : Documentazione del Visual C++ 5.0 sulle API di Windows
               (quel ke e' giusto e' giusto...date a Cesare quel che e'
               di Cesare:))

Questo e' tutto x ora spero ke il menu' sia stato di vostro gradimento e' che
i programmatori della softSENTRY cambino lavoro :)))))

Passiamo ai ringraziamente (sono poki non vi preokkupate:)

Thanks to :

netzus6 "Euclideo" - ke mi appoggia in tutte le kazzate ke faccio.
steFax  "stePhone" - ke mi ha copiato MonkeyInsland 3 e non funziona il
                     secondo cd e sto gia' godendo per quando lo uccidero di
                     mazzate (gggggrrr!!!).
-Neural_Noise      - perke' e' un grande e mi ha fatto spakkare dalle risate
                     anche se lo beccato solo un paio di volte (ciao -NN)
 Kill3xx               - perke' non lo sento da un casino :(
+Malattia              - perke' mi e' simpatico ed e' sempre molto disponibile
 Guybrush "Neuromante" - perke' e' l'unico ke incontro sempre su #crack-it
 ZeroCool & N0bodY88   - ke' hanno pubblicato il mio primo tut sul Newbies#3
 RigoR MorteM          - perke' e' una persona seria :)
 pIGpEN                - ke non conosco ma ke mi piace come scrive e da quello
                         ke ho letto si spakka alla grande:)
                         kissa... magari un giorno ci faremo un Kannone
                         insieme :)  (appr. il secchio lo hai mai provato?)

 saluti anche a tutto RingZer0 e #crack-it, a tutto lo staff di B.F.I. ,
 quello di NewBies e di NetRunners (e a tutti gli spp in generale) ,
 sia a chi mi conosce che a chi non gliene fotte niente di me.

Questo Tut e' stato possibile anche grazie al supporto musicale di :
  Korn - Rage Against The Machine - Primus - The Cure - Buju Banton -
  Perl Jam - Dinosaur Jr. - Exploited - Toy Dolls - CCCP - Nine Inch Nails.

Inoltre un sentitissimo FUCK a :

Bill Gates - perke' ha rotto i koglioni con la sua mania da Hitler
             dell'informatica
Telekom    - perke' e' colpa loro e delle loro tariffe di mmmmerda
             se non ho una connessione alla rete
             (fuck fuck fuck FUUUUUUUUUUUUUUCK ):(

A Quello Stonzo ke ha tradotto Hacker=Pirata_Informatico (vergognati)
           - perke' sembra che un Hacker sia un tipo con una benda su un
             occhio che usa la tastiera con una mano sola perke' nell'altra
             ha un uncino e occupa le sue giornate in "feroci" scorribande
             nell'oceano della "Computer Science".

Vorrei fare inoltre un appello a chi ancora continua a definire Cracker
un "Hacker cattivo" il cui scopo e' quello di entrare in un sistema x poi
distruggerlo :

La volete finire o no !!!!!
Avete skassato u kaz co 'sta storia.
Un cracker studia un programma senza averne i sorgenti x farci
cio' che ritiene opportuno (e'questo il bello:)
e non gliene frega un amatissimo k...o del vostro fottutissimo sistema.

     $$$$$               $$
    $ $$$ $   ΒΆΒΆ         $$     $$$
   $  $ $  $  $$  $$$$   $$    $   $  $     $$
   $  $$   $  $$  $$  $  $$    $$$$$   $   $$
    $ $ $ $   $$  $$  $  $$    $        $ $$
     $$$$$    $$  $$$$   $$$$$  $$$$     $$
                  $$                    $$
                  $$                   $$

  Spedite ringraziamenti, elogi, critiche costruttive a
      Cannabis_Oil@hotmail.com

  Per critiche non/costruttive, insulti, flames e bu......e varie a
      DevNull@Hole.ass

                                                                   (R)ipLey

EOF---------------------------------------------------------------------------