Linux cracking: l'approccio live (acrobat reader)
(Linux reverse engineering avanzato: imported functions)

by SiuL+Hacky
(12 November 1997)
(Tradotto e riadattato da Quequero & Rev20)

Courtesy of fravia's page of reverse engineering

Well, another VERY remarkable essay, that I am proud to present. SiuL+Hacky tackles here once more UNCOVERED ground, and teaches all of you more elements of Linux reverse engineering... you may want to check his good first essay about Linux reverse engineering... a bad omen of these commercial times... even Linux is getting more and more soiled by commercial overbloated applications :-(




LINUX CRACKING: L'APPROCCIO LIVE. ACROBAT READER.

I. Introduzione
---------------

Nel mio primo essay su linux avete capito come fare un porting delle tecniche di windows al mondo di linux. Era stato principalmente dedicato al dead approach perchè è estremamente potente per alcuni tipi di programmi. Ma tristemente, come vedrai, enormi e sovraccaricati programmi stanno entrando nel mondo di linux e se vuoi reversare qualche target hai bisogno  di un po' di debugging (a meno che tu non sia un "signore" del cracking).
Con questo essay proverò ad introdurvi nell'ambiente grafico di linux, XWindows (nessun genere di ambiente porno eh!). Potrebbe sembrare come Windoze ma internamente è MOLTO differente per alcuni aspetti. La differenza principale è che usa l'onnipresente schema client-server. Ad ogni modo, non ho nè il tempo ne la conoscenza per insegnarvi in modo esauriente come lavora, ma vi mostrerò il punto di partenza per il cracking della applicazioni sotto X. In linux potete usare diversi server X, il più popolare è XFree86.

Il proposito di +ORC per il cracking dei tools acrobat-pdf è una buona opportunità per impratichirsi di questi metodi. Vi ho detto, come dissi a lui, che penso che non è giusto perder tempo scrivendo un convertitore da testo a pdf, perchè già esiste e ci sono ancora molti (ed importanti) schemi di protezione non ancora crackati. Così ecco che sto crackando Adobe Acrobat (si, è disponibile per linux, benchè applichi le stesse restrizioni della versione per windoze) con due obiettivi principali:
- Voglio vedere sempre il Menu e la Barra degli strumenti.
- Non voglio copiare le restrizioni del testo e così via.
L'ho preso da un magazine Spagnolo, ma suppongo che sia liberamente distribuibile al sito della Acrobat. Vorrei vedere altre persone reversare il formato pdf.

II. ToolX del Mestiere.
------------------------

Ovviamente qui troverai alcuni tools specifici per X. Molti dei tool li ho nominati nel primo essay applicandoli per X-RE. Molto utile, sarebbe avere il DASM, perchè nonostante andremo ad usare l'approccio live, il listato assembler resta sempre di inestimabile valore. Vi ripeto che il listato ci darà importanti tracce da seguire, ma per un uso migliore leggi le pagine del manuale.

* xwininfo     -----------------------------------------------------------------
Questa utility ti da tutte le informazioni di una specifica finestra. Per default ti chiede di clickare sulla finestra dalla quale vuoi raccogliere informazioni. State molto attenti e non pensate alla "finestra" come fareste per WindoTonno. When clickiamo su una finestra con il mouse, stiamo clickando sulla finestra "fisica", sulla finestra super-genitore (chiamata finestra di root). Ogni finestra (i bottoni per esempio sono finestre figlie) ha un identificatore. Ecco alcuni utili parametri:
- tree: Mostra tutte le finestre (root, parent e child) in maniera ricorsiva. Mostra l'identificatore (conosciuto come Drawables), la dimensione e la posizione.
Ecco un esempio preso per l'Acrobat Reader:
xwininfo: Window id: 0x2800128 "Acrobat Reader"
Root window id: 0x26 (la finestra root) (non ha nome)
   Parent window id: 0x8001ad (non ha nome)
        1 child:
             0x2800129 (non ha nome): ()  272x367+0+0  +527+121
            
             ... alcune altre finestre ...
            
0x2800148 (has no name): ()  24x24+3+3  +530+183; << bottone della barra degli strumenti
0x2800147 (has no name): ()  24x24+27+3  +554+183;<< bottone della barra degli strumenti
0x2800146 (has no name): ()  24x24+51+3  +578+183;<< bottone della barra degli strumenti
0x2800145 (has no name): ()  6x24+75+3 +602+183
0x2800144 (has no name): ()  24x24+81+3  +608+183;<< bottone della barra degli strumenti
0x2800143 (has no name): ()  24x24+105+3  +632+183;<< bottone della barra degli strumenti
0x2800142 (has no name): ()  24x24+129+3 +656+183; << e ancora........
0x2800141 (has no name): ()  6x24+153+3  +680+183
0x2800140 (has no name): ()  24x24+159+3  +686+183
0x280013f (has no name): ()  24x24+183+3 +710+183
0x280013e (has no name): ()  24x24+207+3  +734+183
0x280013d (has no name): ()  24x24+231+3  +758+183
0x280013c (has no name): ()  6x24+255+3 +782+183
0x280013b (has no name): ()  24x24+3+30  +530+210
0x280013a (has no name): ()  24x24+27+30  +554+210
0x2800139 (has no name): ()  6x24+51+30 +578+210
0x2800138 (has no name): ()  24x24+57+30  +584+210
0x2800137 (has no name): ()  24x24+81+30  +608+210
0x2800136 (has no name): ()  24x24+105+30 +632+210
0x2800135 (has no name): ()  6x24+129+30  +656+210
0x2800134 (has no name): ()  24x24+135+30  +662+210
0x2800133 (has no name): ()  6x24+159+30+68 6+210            

            ... alcune altre finestre ...
           
Ovviamente, il primo numero esadecimale è l'identificatore della finestra, che sarà particolarmente utile per altri (o anche questo) tools.
-id: con questa opzione non abbiamo bisogno di clickare su una specifica finestra ma possiamo ottenere informazioni per ogni particolare finestra.
-all: mostra tutte le opzioni disponibili

* xev  ----------------------------------------------------------------------

Questa utility riporta tutti gli eventi coinvolti con qualche finestra. Parametri:
-id: se non gli passiamo un identificatore, xev ci mostrerà una finestra di test nella quale possiamo testare il mouse, la tastiera o qualunque altro tipo di evento.

In alcuni casi possiamo usare questo programma per confrontare gli identificatori. Per esempio se facciamo:
xev -id 0x2800148
xev parte ma noi non sappiamo a quale finestra (figlia) appartiene questo identificatore! Appena muoviamo il mouse sopra le finestre otterremo un messaggio di notifica quando passeremo sopra la finestra che possiede quell'identificatore (MotionNotify).

* xxgdb  --------------------------------------------------------------------

È la versione per Xwindows di gdb. L'unica miglioria è la ButtonBar con alcuni utili comandi. Vedremo alcuni comandi durante il debugging dell'acrobat reader. Spero, in un essay futuro, di mostrarvi alcuni tools un po' più amichevoli, ma per ora questo è il più diffuso e stabile tool che conosco.

* XWindows API Reference  ----------------------------------------------------

Lavorando con i programmi per WinCesso, è diventato importante conoscere la sintassi di alcune API "regolari" come MessageBox, GetDlgItemText e così via. Bene, lo stesso dobbiamo fare con XWindows. Possiamo prendere tutte le definizioni delle chiamate nei file .h che si trovano generalmente nella directory /usr/X11R6/include/X11. Ho trovato particolarmente interessanti alcuni documenti disponibili al sito di xfree86 (ftp.xfree86.org) o, ancora meglio ne potete trovare cercandoli in un mirror di ftpsearch:
xlib.PS.Z   (971 Kb)
Questo è un documento PostScript di 400 pagine dove troverete molte informazioni. È infatti difficile trovare dei libri sulla programmazione sotto XWindows, così se conosci qualche tutorial o qualche documento per i nostri scopi, mandali alla +HCU per essere inseriti nella prossima versione dell'essay (ed anche alla UIC of coz :) NdQuequero

* Convertitore Text-to-pdf -----------------------------------------------------

Questo esiste (c'è un documento interessante alla pagina di fravia riguardo il progetto PDF
),e ne avrai bisogno per testare Acrobat Reader. E' necessario avere un documento
completamente sprotetto e testarlo con uno protetto.
Ho convertito il testo in PDF passando attraverso un passaggio intermedio in PostScript.

mpage: questo programma converte il testo in PostScript facilmente.

GhostScript: questo non è solo un visualizzatore PostScript , ma ha incluso un convertitore da
PostScript a PDF. Se non vuoi andare in fondo con l'utilizzo di GhostScript
 (un bordello per me), utilizza pstoedit, per esempio,per maneggiare questo tipo di task.


III. Reverse Engineering di Acrobat Reader.
-----------------------------------------

Supponiamo che Acrobat sia la directory di base dove è installato il programma.Con facilità scoprirai che puo essere richiamato con "acrobat",un file nella directory Acrobat/bin 
di soli  8467 bytes
Questo approcio è impossibile per questo grande mostro (Vedrai tra poco :),in quanto è soltanto uno Shell Script che chiama il mostro enorme : Acrobat/Reader/intellinux/acroread, 2.511.477 bytes pieni di  nop (credimi, ci ho dato un occhiata). Ok, disassemblalo e il mostro ti apparirà estremamente immenso,una creatura di 38.625.635 bytes and con  1 millione di  linee circa.
Io ti consiglio di non editarlo,e di usare una ricerca "minuta"  (+ o - come quella dei cercatori d' oro ).
Ammira, dai un' ochhiata alla tabella dei simboli  (col nome delle funzioni, dentro e fuori
dal  programma!!!!!. Un regalo  veramente gradevole dai ragazzi della Adobe), ........5 secondi dopo.........
INCUBO: quello che avrebbe dovuto essere una benedizione per i reverser,si è rilevata una maledizione per i cracker : PIU' DI 16000 funzioni (molte delle
quali ripetute) con nomi che stupiscono tipo :

DefaultAnnotHandlerNotifyAnnotAddedToSelection
_XmAllowAcceleratedInsensitiveUnmanagedMenuItems
_XmVirtKeys_siemensWx200FallbackBindingString
_XmVirtKeys_dblclkFallbackBindingString

e cosi via.........
(In winzoz le API avevano nomi strani ma in LinSux ancora d +,possibile che siano tutti psicopatici i programmatori di OS????? NdRev)
Ho cominciato annotare alcune funzioni che potrebbero essere interessanti, quindi ho cominciato a testarle
 ed infine le ho scartate. Sto per mostrarvi le funzioni che mi hanno incuriosito. Alla conclusione dell' essay  realizzerete che sarebbe potuto essere molto facile con una tecnica di cracking  Zen, ma non sono stato  completamente fortunato ( per una volta che non desideravo  essere fortunato!!!) ed ho utilizzato il metodo classico che si utilizza quando il quello Zen fallisce..
 Guardare i seguenti nomi: 
UnixMenubarInitialize
UnixMenuRemoved
UnixPageViewCancelToolButtons
UnixToolbarHide
AVCrypt
DecryptPerms0
DecryptPerms1
UnixDlgSecurityGetValues
UnixCryptGetPasswd

Ho dato uno sguardo al codice di queste funzioni e quindi  le ho verificate col debugger, posizionando breakpoint e osservando i valori di ritorno. Non ho ottenuto niente, quindi ho cercato un altra volta, 
questa volta per la stringa " Hide ". Ho annotato queste funzioni
 
AVToolBarHide
AVMenuBarHide
UnixMenubarWidgetHide

Guardando il codice dell' ultima,ho avuto una botta di culo!!!(una volta tanto :),leggi :

Referenced from jump/call at 08062c64 ;

08048500 <UnixMenubarWidgetHide>    pushl  %ebp
08048501 <UnixMenubarWidgetHide+1>  movl   %esp,%ebp
08048503 <UnixMenubarWidgetHide+3>  subl   $0x10,%esp
08048506 <UnixMenubarWidgetHide+6>  pushl  %ebx
08048507 <UnixMenubarWidgetHide+7>  movl   0x10(%ebp),%ebx
0804850a <UnixMenubarWidgetHide+a>  movb   %bl,0xffffffff(%ebp)
0804850d <UnixMenubarWidgetHide+d>  movl   0x8(%ebp),%eax
08048510 <UnixMenubarWidgetHide+10> pushl  %eax

Reference to function : AVMenubarGetServerData

08048511 <UnixMenubarWidgetHide+11> call   08089090  << Ho sempre creduto che        
                                                     << questa funzione avrebbe potuto 
                                                     << essere importante... Mi sbagliavo
....  code and code ....

08048590 <UnixMenubarWidgetHide+90> movl   0xfffffff8(%ebp),%eax
08048593 <UnixMenubarWidgetHide+93> cmpb   $0x0,0x4(%eax)         << compara qualcosa
08048597 <UnixMenubarWidgetHide+97> jne    080485bc               << se non zero ritorna e fai qualcosa
08048599 <UnixMenubarWidgetHide+99> cmpb   $0x0,0xffffffff(%ebp) << se local var = 0 MOSTRA qualcosa
0804859d <UnixMenubarWidgetHide+9d> je     080485b0               << altrimenti NASCONDI
0804859f <UnixMenubarWidgetHide+9f> movl   0xc(%ebp),%eax
080485a2 <UnixMenubarWidgetHide+a2> pushl  %eax

Reference to function : UnixMenubarWidgetHideInternal

080485a3 <UnixMenubarWidgetHide+a3> call   08048480
080485a8 <UnixMenubarWidgetHide+a8> addl   $0x4,%esp
080485ab <UnixMenubarWidgetHide+ab> jmp    080485bc
080485ad <UnixMenubarWidgetHide+ad> nop   
080485ae <UnixMenubarWidgetHide+ae> nop   
080485af <UnixMenubarWidgetHide+af> nop   

Referenced from jump/call at 0804859d ;

080485b0 <UnixMenubarWidgetHide+b0> movl   0xc(%ebp),%eax
080485b3 <UnixMenubarWidgetHide+b3> pushl  %eax

Reference to function : UnixMenubarWidgetShowInternal

080485b4 <UnixMenubarWidgetHide+b4> call   080484d0
080485b9 <UnixMenubarWidgetHide+b9> addl   $0x4,%esp

Referenced from jump/call at 08048597 ; 080485ab ;

080485bc <UnixMenubarWidgetHide+bc> movl   0xffffffec(%ebp),%ebx
080485bf <UnixMenubarWidgetHide+bf> movl   %ebp,%esp
080485c1 <UnixMenubarWidgetHide+c1> popl   %ebp
080485c2 <UnixMenubarWidgetHide+c2> ret

Che cosa accade con questa variabile importante? Se guardi l'' istruzione
804850, è copiata da uno dei parametri della funzione. Con un pò di teoria di
base sui parametri (se no,leggi i files di Fravia su:s filemon series)
tu sai che :

1°  parametro è localizzato a [bp+0x8]
2°  parametro è localizzato a [bp+0xc]
3°  parametro è localizzato a [bp+0x10]

(chiaramente, consideriamo un parametro = una word come lunghezza). Ok, diamo un occhiata
alla funzione che chiama (questa funzione è chiamata da 08062c64). Fai attenzione ai parametri:


(... alcune righe non interessanti ...)
Reference to function : AVDocGetKioskBool

08062c24 <UnixDocViewUpdateVisibility+44> call   0807d290      <<<< la funzione ritorna 1 or 0 in  eax
08062c29 <UnixDocViewUpdateVisibility+49> addl   $0x8,%esp
08062c2c <UnixDocViewUpdateVisibility+4c> movl   %eax,%edx
08062c2e <UnixDocViewUpdateVisibility+4e> movsbl %dl,%eax      << il valore ritornato in eax,di nuovo
08062c31 <UnixDocViewUpdateVisibility+51> jmp    08062c42      << guarda questi nop,
08062c33 <UnixDocViewUpdateVisibility+53> nop                  << nop                  << tipo di  mega-allineamento x pentium  or spazio per il  patching?
08062c33 <UnixDocViewUpdateVisibility+53> nop   
08062c34 <UnixDocViewUpdateVisibility+54> nop   
08062c35 <UnixDocViewUpdateVisibility+55> nop   
08062c36 <UnixDocViewUpdateVisibility+56> nop   
08062c37 <UnixDocViewUpdateVisibility+57> nop   
08062c38 <UnixDocViewUpdateVisibility+58> nop   
08062c39 <UnixDocViewUpdateVisibility+59> nop   
08062c3a <UnixDocViewUpdateVisibility+5a> nop   
08062c3b <UnixDocViewUpdateVisibility+5b> nop
08062c3c <UnixDocViewUpdateVisibility+5c> nop   
08062c3d <UnixDocViewUpdateVisibility+5d> nop   
08062c3e <UnixDocViewUpdateVisibility+5e> nop   
08062c3f <UnixDocViewUpdateVisibility+5f> nop   

Referenced from jump/call at 08062c0b ;

08062c40 <UnixDocViewUpdateVisibility+60> xorl   %eax,%eax

Referenced from jump/call at 08062c31 ;           << noi SALTIAMO QUA !!!!!!!!!!
                                                 << altri  nop,se +orc li vedesse  :-(
08062c42 <UnixDocViewUpdateVisibility+62> jmp    08062c55
... (10 more nops)...   
08062c4f <UnixDocViewUpdateVisibility+6f> nop   

Referenced from jump/call at 08062c05 ;
08062c50 <UnixDocViewUpdateVisibility+70> movl   $0x1,%eax

Referenced from jump/call at 08062c42 ;        << noi SALTIAMO QUA!!!
08062c55 <UnixDocViewUpdateVisibility+75> pushl  %eax     <<3° parametro salvato
                                                            << ricorda eax= valore ritornato
08062c56 <UnixDocViewUpdateVisibility+76> movl   0x8(%ebp),%eax
08062c59 <UnixDocViewUpdateVisibility+79> movl   0x10(%eax),%edx
08062c5c <UnixDocViewUpdateVisibility+7c> pushl  %edx     <<2° parametro salvato
08062c5d <UnixDocViewUpdateVisibility+7d> movl   0x8(%ebp),%eax
08062c60 <UnixDocViewUpdateVisibility+80> movl   0xc(%eax),%edx
08062c63 <UnixDocViewUpdateVisibility+83> pushl  %edx      <<1° parametro salvato
Reference to function : UnixMenubarWidgetHide
08062c64 <UnixDocViewUpdateVisibility+84> call   08048500

E' praticamente immediato che,se la funzione AVDocGetKioskBool ritorna 0 noi siamo BRAVI RAGAZZI!!!. Facciamo ritornare allora SEMPRE questa funzione a 0. Tu potresti patchare nella vecchia maniera,ma ora
stiamo per imparare ad utilizzare le capacità del  xxgdb :

1) Lancia acrobat reader . Guarda il suo Process Identifier (PID)
2) Lancia xxgdb
3) Esegui il comando"file (<tuo percorso>)/Acrobat/Reader/intellinux/bin/acroread,
   che caricherà i simboli. Non spaventarti se xxgdb vocifera riguardo errori.......
4) Stiamo per impostare il debugger in un processo Attivo. Per questa
   ragione, esegui il comando"attach PID", dove PID E' UN  NUMERO, l' identificatore
di processo di  acroread (utilizza ps per il  checking)
5) Atterrerai probabilmente nel mezzo di una chiamata di sistema, questo è OK.
6) Lancia il comando "cont" per continuare l'esecuzione.
7) Quando vuoi fermarti ,premi Control-C.

Questa è una porzione di codice importante della funzione AVDocGetKioskBool:

0807d3d2 movl   %edx,%eax
0807d3d4 jmp    0807d3e0

(... altre dozzine di nop ...)

Referenced from jump/call at 0807d2bb ; 0807d3d4 ;

0807d3e0 leal   0xfffffff0(%ebp),%esp
0807d3e3 popl   %ebx
0807d3e4 popl   %esi
0807d3e5 movl   %ebp,%esp
0807d3e7 popl   %ebp
0807d3e8 ret 

L'istruzione a 807d3e0 è sempre chiamata da 807d3d4, l' altra 
referenza è solo un  "ritorno veloce" che da un errore. Questo è quello
che farà il crack mentre lavora con il debugger. Vedrai tra poco come questo sia 
un potentissimo , con capacità aggiunte in softice non da molto tempo.

(xxgdb) questo è il prompt:

(xxgdb) br *0x0807d3d2 if $edx==1
Breakpoint 1 a 0x0807d3d2
(xxgdb) commands
>silent
>set $edx=0
>cont
>end
(xxgdb)

Veramente potente vero? ? Se ti interessa sapere lo stato dei breakpoint,digita "info br".
Bene, se ora esegui il comando "cont", tu avrai sempre menu, toolbars and
il resto visibile, anche se alla Adobe non vogliono :-).
Credo che il codice sottostante sia abbastanza facile da capire...

Dedichiamoci ora alla seconda parte:di cosa si tratta ? in poche parole : 'copiare il testo'.
Come ti ho detto gia prima,non sono stato fortunato.In principio ho provato 
lo stesso gioco del primo passo:prova e sbaglia,pensarci un pochino, 
guardare le funzioni *interessanti*.... e mi sono perso in un mare immenso 
di stupide funzioni. Ho navigato sopra tonnellate di funzioni (come è poetico +Fravia :), 
ed ero vicino al successo, tu vedrai che i nomi delle funzioni sono di nuovo
ovvi (e stupidi :),ma fino a quando tu prendi questo bersaglio in un blocco unico
non realizzerai veramente che cosa sta succedendo.
Io ero sempre confuso da X buffering, eventi grafici che non erano implementati
immediatamente, e 5 o 6 buttoni sulla toolbar che erano disegnati contemporaneamente in un colpo solo.

Dopo un giorno di test inutili,ho deciso di atturare il solito metodo, e dopo
aver cominciato da un punto dubbio,ho raggiunto il codice che stavo osservando. Io volevo
soltanto capire dove venivano disabilitati i bottoni e in seguito,da li, fare il trace back:
Reverse Engineering cosi come tutti l' hanno imparata (Io non ancora c***arola NdRev)
Ho studiato alcune  API di Xwindows , e ho avuto inormazioni riguardo gli eventi.
Per *fixare* il problema dei bottoni bufferizzato,ho letto la prima pagina dell X server:

"Tutte le applicazioni scritte con l' X Toolkit Intrinsics accettano automaticamente
le seguenti opzioni:
  [...]
-synchronous
       Questa opzione indica che le richieste all' X server dovrebbero 
       essere mandate in modo sincrono, invece che asyncron.  
       Poichè Xlib normalmente bufferizza le richieste al
       server, gli errori non  necessariamente sono riportati immediatamente
       dopo che avvengono. Questa opzione disabilita il buffering in modo
       che le applicazioni possano essere debuggate. Non dovrebbe mai essere
       utilizzata con un programma funzionante."
      
Quindi da ora in poi lanciare: acrobat -synchronous
      
Perfetto, ora dobbiamo trovare la X Call.. Non ho trovato la funzione che 
stavo cercando,quindi ho deciso di partire da una funzione "solida" e quindi
testare l' albero delle call fino a quando la funzione bersaglio non veniva furori
Questa sembrava essere una funzione "solida":

AVAppSelectLegalTool

Come ho trovato questa funzione ? Beh,, ti ho detto che stavo cercando qualcosa riguardo la 
ToolBar, una delle più interessanti (al nostro fine) è UnixToolBarUpdateButtonStates,
che è chiamata da AVAppSelectLegalTool.

Un trucchetto che si è rilevato utile nel  X debugging: Ho trovato un bug (Non so se è
un problema di gdb o di X server o di gestione delle finestre), quando breakki il 
programma e questo è impegnato con un certo task di interfaccia, focus non puo essere
ritornato con successo al  xxgdb, e tutte le applicazioni X si inchiodano. In questo caso devi
aprire una nuova console virtuale e uccidere tutti gli xxgdb process (e quindi
rilanciarli). Se vuoi evitare questa situazione, devi interrompere il programma
in qualche istruzione precedente "sicura" (probabilmente in un altra funzione) senza problemi di 
focus-back . Quindi xxgdb darà il focus e tu farai ripartire l'esecuzione
(comando "cont" ) e il focus non tornerà ad Acrobat (resterà in background)
e potrai cosi breakkare nel  "codice pericoloso". Ti sto dicendo questo 
adesso perchè l' inizio di questa funzione è ok per un breakpoint di "sicurezza"
nel tentativo di trovare cosa nasconde e disabilita i bottoni sul Toolbar.

Ora uno schema di AVAppSelectLegalTool:

0x806ccc0 AVAppSelectLegalTool

  AVAppGetActiveDoc         (Un parametro)
  AvAppGetActiveTool
  ToolIsEnabled              (7 parametri)
  AVAppGetDefaultTool
  AVAppSetActiveTool        (7 parametri)
  AVAppGetToolBar
  AVToolBarUpdateButtonStates
 
0x806cd19 end

Nomi veramente interessanti ma nient'altro . Dopo un pò di ore l'unico fatto positivo 
era che i bottoni venivano aggiornati (CMQ per la prima volta sia senza protezione ,che
con,vengono riscritti nuovamente; in questo caso , "pulendo" la finestra
che li nasconde, or cambiando il desktop) in AVToolBarUpdateButtonStates. Per
la ricerca del  task, i breakpoints temporanei sono veramente utili, lo sai,
 utilizzali e buttali via.
Per esempio scrivendo questo::

(xxgdb)br *AVAppSelectLegalTool
(xxgdb)cont
  ... fa qualcosa come caricare qualche dannato file pdf . Si fermerà.
 
(xxgdb)tbr *AvAppGetActiveTool
(xxgdb)cont

  ... un blocco temporaneo è settato. Ora puoi vedere che cosa succede mentre   ... 
AVAppGetActiveDoc è eseguito. Si ferma at AvAppGetActiveTool
 
(xxgdb)tbr *ToolIsEnabled
(xxgdb)cont

... e cosi via... capito ?

Ok, andiamo avanti con AVToolBarUpdateButtonStates. Qui c'è una cosa interessante:

  080bbf7 AVToolBarUpdateButtonStates
  080bbfa0 call   *%ebx
  080bbfb3 call   08038ed8 <_init+2168>
 
o se tu vuoi:

  080bbf7 AVToolBarUpdateButtonStates
  080bbfa0 call UnixEnumChildWidget
  080bbfb3 call ASListEnum
 
Assicurati che la funzione sia quella che ci interessa. Se tu guardi
il listato di questa funzione, ti accorgerai che fa una call indiretta a una funzione
VERAMENTE importante, chiamata SetStateEnumProc. Qui c'è il codice commentato:

0805ecf0  pushl  %ebp
0805ecf1  movl   %esp,%ebp
0805ecf3  subl   $0x8,%esp
0805ecf6  pushl  %ebx
0805ecf7  movl   0x8(%ebp),%eax
0805ecfa  movl   0x4(%eax),%edx
0805ecfd  movb   0x14(%edx),%al
0805ed00  andb   $0x8,%al
0805ed02  testb  %al,%al
0805ed04  jne    0805ed10
0805ed06  jmp    0805ed70
0805ed08  nop   
...   
0805ed0f  nop   

Referenced from jump/call at 0805ed04 ;

0805ed10  movl   0x8(%ebp),%eax
0805ed13  movl   %eax,0xfffffff8(%ebp)
0805ed16  movl   $0x0,0xfffffffc(%ebp)

Referenced from jump/call at 0805ed63 ;    <QUI LOPPA (se loppa non è un TM,lo registro io NdRev :)

0805ed1d  movl   0xfffffff8(%ebp),%eax:
0805ed20  movl   0xfffffffc(%ebp),%edx;   <<CONTINUIAMO QUI !!
0805ed30  movl   0x10(%ebp),%eax; << CARICA QUALCOSA
0805ed33  pushl  %eax;                     << LO SALVA
0805ed34  movl   0xfffffff8(%ebp),%eax; << CARICA QUALCOSA 
0805ed37  movl   0xfffffffc(%ebp),%edx;     << CARICA L'INDEX
0805ed3a  movl   %edx,%ecx;       << MUOVE L'INDEX IN ECX
0805ed3c  leal   0x0(,%ecx,4),%edx; << CREA UN PUNTATORE IN EDX
0805ed43  movl   0x74(%eax),%eax; << CARICA IL SECONDO INDEX
0805ed46  movl   (%eax,%edx,1),%edx;<< DOPPIO INDIRIZZAMENTO QUI
0805ed49  pushl  %edx;           <SALVA IL VALORE
0805ed4a  movl   0xc(%ebp),%ebx; << CARICA L'INDIRIZZO DELLA FUNZIONE
0805ed4d  call   *%ebx;           <<CALL a SetStateEnumProc
0805ed4f  addl   $0x8,%esp,           << RITORNA IN EAX
0805ed52  movb   %al,%al
0805ed54  testb  %al,%al
0805ed56  jne    0805ed60;  << SALTA AL DI SOTTO SE  RETURNED != 0
0805ed58  jmp    0805ed70;  << ALTRIMENTI FA  JUMP ALLA FINE DELLA FUNZIONE
0805ed5a  nop   
...   
0805ed5c  nop   

Referenced from jump/call at 0805ed56 ;

0805ed60  incl   0xfffffffc(%ebp); << INCREMENTA IL PUNTATORE
0805ed63  jmp    0805ed1d;    << SALTA VIA

Una chiamata a SetStateEnumProc per ogni pulsante. La prima volta,abbiamo
alcune 'azioni' (non sappiamo ancora quali) per un bottone particolare. Non amo
gli essays che contengono listati pesanti di codice,quindi ecco uno schema delle
funzioni e ti dirò successivamente cosa ci interessa di queste:

0805aec0 SetStateEnumProc
  call XtVaGetValues
  call AVToolButtonIsSeparator
  call AVToolButtonIsEnabled
  call XtSetSensitive
  call XtIsSubclass   
  call AVToolButtonIsMarked
  call XacroToolButtonSetMarked
end

XtSetSensitive E' LA NOSTRA FUNZIONE.Questa abilita o disabilita i bottoni. Se diamo un
occhiata all' API:

extern void XtSetSensitive(
    Widget               /* widget */,
    _XtBoolean          /* sensitive */
);
       
Hence sono interessati nel secondo parametro , che è pushato nel primo posto.
 Alcuni dettagli in assembler sulla funzione:

Reference to function : AVToolButtonIsEnabled

0805aef4  call   080bb3a0; << ritorna 1 or 0 in eax
0805aef9  addl   $0x4,%esp
0805aefc  movl   %eax,%eax
0805aefe  movzwl %ax,%edx; << valore ritornato in edx adesso
0805af01  pushl  %edx;  << qui c'è il nostro parametro ****
0805af02  movl   0x8(%ebp),%eax
0805af05  pushl  %eax

Reference to function : XtSetSensitive

0805af06<SetStateEnumProc+46> call   08037dc8 <_init+1058>

Ora capisci che cosa intendevo per  zen e fortuna. Se io avessi seguito 
questa funzione ... (attualmente io ci avevo gia provato, ma acrobat era in
modalità asynchrona e io ero confuso,lo sai la vita è strana).Quindi 
questa funzione è il giudice che condanna i bottoni all' inferno o al paradiso :). Questa
è la parte *calda*(VM18,non vale crakkare il test dell'età :) della funzione :

AVToolButtonIsEnabled       (... istruzione dannosa x la tua salute ...)

080bb43a  call   *%ebx      << questa call indiretta chiama  StdComputeEnabledSelChange
                            << il valore ritornato è salvato in eax come al solito
            
080bb43c  addl   $0x4,%esp
080bb43f  movl   %eax,%eax;              << Non lo capisco..........
080bb441  movw   %ax,0xfffffffe(%ebp);  << salva il valore  booleano
080bb445  addl   $0xfffffff8,0x820b904
080bb44c  jmp    080bb45d;                << JUMPA
080bb44e  nop   
080bb44f  nop   

Referenced from jump/call at 080bb42b ;

080bb450  addl   $0xfffffff8,0x820b904
080bb457  movw   $0x0,0xfffffffe(%ebp)

Referenced from jump/call at 080bb44c ;   <noi jumpiamo qua !!!
080bb45d  pushl  $0x0

Reference to function : AVAppSetBusy

080bb45f  call   080700f0 <AVAppSetBusy>;  <<bla bla bla
080bb464  addl   $0x4,%esp

Referenced from jump/call at 080bb3dd ; 080bb3f2 ;

080bb467  movw   0xfffffffe(%ebp),%ax;  << muove in eax il valore booleano
080bb46b  movzwl %ax,%edx;              << altre istruzioni stupide
080bb46e  movl   %edx,%eax
080bb470  jmp    080bb480;             << salta all fine
 
Non preoccupare questo non è infinito, siamo vicino al crack, ma dobbiamo andare a questa funzione " accademica " StdComputeEnabledSelChange. CMQ, potete vedere che questa funzione ha un parametro. Per ogni tasto ma " il text-button " il parametro salvato a 0 e per il tasto dannato il parametro è 0x10. Ora vedrai come tutto ha senso:

080baef0 StdComputeEnabledSelChange

(... bla bla bla ...)
080baf22  movl   0x8(%ebp),%eax;    << prendi il parametro
080baf25  pushl  %eax;               << salva il parametro nello stack
080baf26  movl   0xfffffffc(%ebp),%eax;
080baf29  pushl  %eax;               << salva un altro parametro
Reference to function : AVDocCheckPermission


080baf2a  call   0807c8f0 <AVDocCheckPermission>

E ultimo ma non per importanza (Non dimenticarti il parametro del primo PUSH):

(... bla bla bla ...)
Reference to function : AVDocGetPDDoc
0807c944  call   0807ca90 << mette il puntatore di alcune strutture pdf in eax
0807c949  addl   $0x4,%esp
0807c94c  movl   %eax,%eax
0807c94e  pushl  %eax:  << salva il puntatore

Reference to function : PDDocGetPermissions
0807c94f  call   08038828 <_init+1ab8>       << questa funzione ritorna in eax la word permission
0807c954  addl   $0x4,%esp
0807c957  movl   %eax,%eax
0807c959  movl   %eax,%edx   << copia  permission in edx
0807c95b  andl   0xc(%ebp),%edx; << AND con il parametro !!!!
0807c95e  cmpl   %edx,0xc(%ebp)
0807c961  sete   %al
0807c964  movzbl %al,%edx
0807c967  movl   %edx,%eax
0807c969  jmp    0807c970
0807c96b  nop   
0807c96c  nop   
0807c96d  nop   
0807c96e  nop   
0807c96f  nop   

Referenced from jump/call at 0807c93d ; 0807c969 ;
0807c970  movl   %ebp,%esp
0807c972  popl   %ebp
0807c973  ret  

Siamo alla conclusione del nostro lungo viaggio. La world permission per un documento non protetto è 0x7fff (piuttosto curioso: -).

Per una spiegazione di questo 7FF, guarda +Zer0's essay:

Attualmente il valore del byte più significativo è  stato trasformato di un ordine superiore al bit,cioè il byte a 7F 
e il byte meno significativo incrementato di 1,quindi il valore desiderato a questa posizione 
è 7FFD invece che FFFC. 

Puoi realizzare che PDDocGetPermissions no è all' interno di acroread. 
E' una funzione importata. 
Il codice è localizzato in una libreria (Acrobat/Reader/intellinux/lib/libreadcore.so.3). 
Puoi disassemblarla (Non voglio stressarti ancora di qui in questo essay :-) 
e la funzione ritorna l'input come parametro+0x78, quindi l'offset di  
permesso è  0x78.
Ora puoi crakkarlo nel modo che preferisci. Puoi patchare la libreria, sovrascrivere
alcuni nops. Se stai lavorando con xxgdb,ti suggerisco di patchare
AVDocGetPDDoc, e non solo il ritorno del puntatore ma "inizializzare" il permesso.
Questi sono i comandi:

(xxgdb)br *0807cac3   (l' indirizzo di ritorno di AVDocGetPDDoc)
(xxgdb)commands
>silent
>set *($eax+0x78)=0x7fff
>cont
>end

Ci sono un mucchio di cose da fare (esaminando a fondo la word permission, routines di enryption...),ma spero mi permetterai di non farlo adesso :). 
Spero che questa versione ti possa aiutare anche per la versione di windows, o almeno 
darti supporto per crakkare altre applicazioni linux di tipo commerciale.


"Long is the way and hard, that out of Hell leads up to the light"

(c) SiuL+Hacky 1997. All rights reversed

You are deep inside fravia's page of reverse engineering,  
choose your way out:


redBack to the PDF-project

redhomepage
redlinks 
redanonymity 
+ORC

redstudents' essays

redacademy database


redtools

redcocktails

redantismut CGI-scripts

redsearch_forms

redmail_fravia


redIs reverse engineering legal?