2015-07-31 20 views
17

Quando Oracle compila una stored procedure, memorizza l'AST per la procedura in formato DIANA.Come accedere all'AST (abstract syntax tree) per una stored procedure PL/SQL?

  • come accedere a questo AST?
  • ci sono strumenti integrati per l'elaborazione di questo AST?
+1

Non mi sono mai imbattuto nell'abbreviazione AST. L'unica volta che ho visto qualcosa su DIANA è nella sezione Limiti del programma PL/SQL della documentazione http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/limits.htm che parla di come PL/SQL utilizza una variante di DIANA e un Interface Definition Language (IDL). Perché vorresti accedervi o elaborarlo? Non conosco alcun modo per accedervi, anche se sono sicuro che probabilmente potresti trovare una combinazione di tabelle 'x $' e bloccare i dump per guardarlo se sei veramente determinato. Ma probabilmente c'è un modo più semplice per ottenere tutto ciò di cui hai bisogno. –

+0

[Informazioni su 'SYS.IDL_xxx $'?] (Http://docs.oracle.com/cd/B14117_01/appdev.101/b10795/adfns_pc.htm) – mustaccio

+0

Alexandre Porcelli ha pubblicato [un parser PL/SQL 11gR2 per Antlr] (https://github.com/porcelli/plsql-parser) su Github. Ovviamente non built-in, e probabilmente non completo, ma forse si adatta alle tue esigenze. – APC

risposta

8

C'è un pacchetto non documentato DUMPDIANA che ha lo scopo di scaricare Diana in un formato leggibile dall'uomo.

Il file $ ORACLE_HOME \ rdbms \ admin \ dumpdian.sql dice "La documentazione è disponibile in /vobs/plsql/notes/dumpdiana.txt". Non riesco a trovare quel file, e senza di esso possiamo solo indovinare il significato di alcuni parametri. Utilizzo base di DUMPDIANA è la seguente:

SQL> show user 
USER is "SYS" 
SQL> @?\rdbms\admin\dumpdian 

Library created. 


Package created. 


Package body created. 

create or replace procedure hello_world 
    2 as 
    3 begin 
    4 dbms_output.put_line('hello world'); 
    5* end; 


Procedure created. 

SQL> set serveroutput on 
SQL> execute sys.DUMPDIANA.dump('HELLO_WORLD'); 
user: SYS 

PL/SQL procedure successfully completed. 

A questo punto una coppia di file dovrebbe essere stato creato nella cartella $ORACLE_BASE/diag/rdbms/orcl12c/orcl12c/trace. I due file sembrano seguire la convenzione di denominazione:

orcl12c_ora_{PROCESS}.trc 
orcl12c_ora_{PROCESS.trm 

Dove il file TRC è una versione leggibile del file TRM corrispondente, e {PROCESSO} è l'ID di processo del sistema operativo. Per trovare questo utilizzare la seguente query dalla stessa sessione:

select p.spid from v$session s,v$process p 
where s.paddr = p.addr 
and s.sid = sys_context('USERENV','SID'); 

Per esempio, se l'ID di sessione era 8861 poi da una shell Bash è possibile visualizzare i risultati utilizzando:

vim $ORACLE_BASE/diag/rdbms/orcl12c/orcl12c/trace/orcl12c_ora_8861.trc 

Il risultato è interessante ... se non particolarmente intuitivo! Ad esempio ecco un frammento del file prodotto. Nota la stringa HALE_WORLD letterale.

PD1(2):D_COMP_U [ 
    L_SRCPOS : row 1 col 1 
    A_CONTEX : 
PD2(2):  D_CONTEX [ 
      L_SRCPOS : row 1 col 1 
      AS_LIST : < > 
     ] 
    A_UNIT_B : 
PD3(2):  D_S_BODY [ 
      L_SRCPOS : row 1 col 1 
      A_D_ : 
PD4(2):   DI_PROC [ 
       L_SRCPOS : row 1 col 11 
       L_SYMREP : HELLO_WORLD, 
       S_SPEC : PD5^(2), 
       S_BODY : PD8^(2), 

Un paio di note. L'ho eseguito come SYS, che, come sappiamo, non è una buona pratica, non è una ragione per cui io sappia perché non dovresti concedere i privilegi su DUMPDIANA a un utente normale. Tutte le procedure che usi vanno nello stesso file: se elimini quel file, smette di funzionare e dovrai iniziare una nuova sessione. Se smette di funzionare, l'avvio di una nuova sessione a volte sembra risolvere il problema.

+0

@ jon-heller Grazie per la tua modifica. Dopo alcune (o molte) ipotesi, ho scoperto che scarica i dati in un file, il che è piuttosto fastidioso in quanto rende difficile elaborare ulteriormente i dati all'interno del db. Potremmo leggerlo usando una tabella esterna, e poi fare una sorta di analisi su di esso, o forse dumpdiana è la traccia sbagliata e c'è un altro modo per ottenere l'AST in un formato più relazionale. – James

+0

Questo aggiornamento sicuramente risponde alla domanda. Sfortunatamente i risultati sono ancora probabilmente troppo criptici per essere utili. Lascio che la ricompensa rimanga aperta per alcuni giorni per vedere se qualcuno può migliorarlo. –

+0

Per chiunque stia ricercando questo: questo documento http://www.dtic.mil/docs/citations/ADA272792, che sembra provenire direttamente dalla credenza dei Mad Men, descrive in dettaglio il linguaggio DIANA. – James

2

Ecco un eccellente tutorial su DIANA e IDL nel PDF How to unwrap PL/SQL di Pete Finnigan, principale consulente di Siemens al momento della stesura, specializzato nella ricerca e nella protezione di database Oracle.

Tra le altre cose molto interessanti imparerete che:

  • DIANA è scritto giù come IDL (Interface Definition Language).
  • Le 4 tabelle in cui è memorizzato IDL (IDL_CHAR $, IDL_SB4 $, IDL_UB1 $ e IDL_UB2 $)
  • Wrapper PL/SQL è semplicemente DIANA scritto come IDL.
  • Dumpdiana non è installato di default, è necessario assicurarsi che anche i pacchetti DIANA, PIDL e DIUTIL PL/SQL siano installati ed è necessario eseguirlo come SYS.
  • Come scaricare l'albero DIANA e capirlo.
  • Come ricostruire il codice sorgente PL/SQL da DIANA.
  • Come scrivere un un wrapper PL/SQL.
  • Limitazioni di un wrapper basato su API PL/SQL.
  • Limitazioni dell'API PL/SQL stessa.
  • Come enumerare i nodi e gli attributi DIANA.
  • Un proof of concept un-wrapper.

È possibile trovare his website here. C'è così tanto contenuto lì. Troverete awesome papers about Oracle security e anche un sacco di useful security tools sviluppato non solo da lui ma anche da altri autori.

Meglio ancora, puoi metterti in contatto con lui se dopo la lettura hai ancora domande.

+0

Queste sono alcune informazioni teoriche utili ma sembrano centinaia di ore di lavoro lontano da una soluzione pratica. –