2013-03-11 17 views
7

C'è un modo per far sì che SBCL acquisisca il valore di un registro CPU in un determinato punto del mio programma e lo stampi come un intero?C'è un modo per far sì che sbcl stampi il valore di un registro della CPU?

Devo usare gdb?

+4

Che cosa avete bisogno di questo per? Nel bel mezzo di una funzione Lisp, non si può mai essere sicuri di quale sia lo specifico registro utilizzato per cui stampare il contenuto di un registro specifico non avrebbe molto senso. –

+2

Si prega di chiarire perché è necessario conoscere il valore di un registro CPU. In generale, non è molto utile conoscere i valori di registro poiché sono gestiti dal compilatore. In SBCL è possibile definire VOP (Virtual machine OPeration) con codice assembly - vedere http://sbcl-internals.cliki.net/Adding%20VOPs . –

+0

Sto provando a scrivere un programma vulnerabile a un buffer overflow e codice per sfruttarlo sovrascrivendo l'indirizzo di ritorno sullo stack. –

risposta

10

Sì, è possibile accedere ai registri della CPU utilizzando VOPs (Virtual Operations). In VOP è possibile scrivere codice anche in assembly, quindi in questo senso è possibile utilizzare VOP come l'assembly esteso di gcc.

Quindi, ecco un esempio di VOP e una funzione correlata per eseguirlo. Il get-cpuid-eax VOP riceve due argomenti senza segno a 32 bit come input, li memorizza in eax e ecx, esegue cpuid istruzione, e restituisce il valore di registro eax dopo la funzione cpuid a get-cpuid-eax che ha chiamato il VOP. La funzione get-cpuid-eax memorizza quindi il valore in *result*. È possibile stampare facilmente il valore con (format t "~a" *result*).

Nota: c'è qualche problema (bug in SBCL o nel mio codice?) Che causa questo codice da non eseguire senza problemi sempre. Solitamente la ricompilazione e il ricaricamento aiutano. Ho confermato l'uscita cpuideax con l'assembly esteso gcc ed eseguendo un programma di assemblaggio x86-64 in gdb. Tutti danno gli stessi risultati per gli stessi valori in eax e ecx.

Edit: cambiato funzione & VOP nomi ai get-cpuid-eax per evitare confusione con i nomi delle variabili.

Modifica: formattazione codice fisso con slimv.

 
(sb-vm::defknown get-cpuid-eax 
       ((unsigned-byte 32) (unsigned-byte 32)) 
       (unsigned-byte 32) 
       (sb-c::foldable sb-c::flushable sb-c::movable)) 

(sb-vm::define-vop (get-cpuid-eax) 
    (:policy :fast-safe) 
    (:translate get-cpuid-eax) 
    (:args 
    (my-eax :scs (sb-vm::unsigned-reg) :target eax) 
    (my-ecx :scs (sb-vm::unsigned-reg) :target ecx)) 
    (:arg-types sb-vm::unsigned-num sb-vm::unsigned-num) 
    (:temporary 
    (:sc sb-vm::unsigned-reg :offset sb-vm::eax-offset) 
    eax) 
    (:temporary 
    (:sc sb-vm::unsigned-reg :offset sb-vm::ecx-offset) 
    ecx) 
    (:results 
    (my-result :scs (sb-vm::unsigned-reg))) 
    (:result-types sb-vm::unsigned-num) 
    (:generator 
    0 
    (sb-vm::move eax my-eax) 
    (sb-vm::move ecx my-ecx) 
    (sb-vm::inst cpuid) 
    (sb-vm::move my-result eax))) 

(defun get-cpuid-eax (my-eax my-ecx) 
    (declare (type (unsigned-byte 32) my-eax my-ecx) 
      (optimize (speed 3) (safety 0))) 
    (defparameter *result* (get-cpuid-eax my-eax my-ecx))) 

Alcuni siti web con brevi VOP che ho trovato molto utile durante la codifica questo:

Dmitry Kaliyanov's article "Добавление примитивов виртуальной машины SBCL" ("Adding primitive virtual machines of SBCL", in Russian)

the Lisp code for Dmitry Kaliyanov's article (above)

Dmitry Ignatiev's blog entry: SBCL, x86, SSE (in Russian)

Christophe Rhodes' presentation slides (pdf): Unportable but fun: Using SBCL Internals

kurohuku's blog entry: "SBCLでCPUID" (in Japanese)

swap-bytes source code file sbcl-vops.lisp

Spero che questo aiuti.

+0

Perché stai memorizzando il risultato in '* risultato *' invece di restituirlo? E perché un 'defparameter' all'interno di un' defun' ?! E c'è una ragione particolare per avere '(sicurezza 0)'? –

+0

@DanRobertson La mia risposta è una dimostrazione del concetto (che si può fare), non un codice a livello di impresa. Sei libero di pubblicare la tua risposta. – nrz

+0

Suppongo che mi aspettassi una risposta del tipo "se non fai X allora il vop non kickerà" –

Problemi correlati