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