[SWITCH]CTU: Cage The Unicorn,il primo emulatore di Debug su SwitchTempo di lettura : 4 min

Il team reswitched è sempre al lavoro su nuove scoperte della nuova console Nintendo Switch.Per questo motivo arriva CTU (Cage The Unicorn)il primo emulatore di debug. Non è il solito emulatore che permette di avviare giochi,non ha alcun supporto per la grafica, il suono, l’input o qualsiasi tipo di elaborazione anche remota ma è solo per eseguire interi sysmodules o applicazioni interattive, eseguire il tracciamento e il debug del codice, test exploit, fuzz e altro ancora.Per l’utente finale l’emulatore è difficile da utilizzare,pur seguendo la procedura descritta nella guida nei minimi particolari.E’ richiesta la conoscenza del linguaggio di programmazione Python.

Installazione

Installare Unicorn da github e assicurarsi di aver installato Python 2.7.x.

Creare una directory chiamata SwitchFS/archivese copiare tutti i file .binfile di archivio di sistema in quello, se un sysmodule richiede l’esecuzione.

Utilizzo

Il caso più semplice è quello di eseguire un sysmodule. Per impostarlo, eseguire:

./addtitle.sh target source

Dove targetè il nome della directory (generalmente ti consigliamo di includere il nome del sistema e la versione del sistema, ad esempio pctl30) per creare il sourcedella directory contenente i binari.

La directory di destinazione verrà creata insieme a un file run.pye i load.yamldi origine verranno copiati. Per eseguirlo, eseguite semplicementepython target/run.py

Puoi vedere uno scheletro vuoto nella directory skeletonSample.

load.yaml

Il file load.yamldefinisce ciò che deve essere caricato in un processo. È un dizionario con le seguenti chiavi ammissibili:

  • nxonronso– Nome file singolo (stringa) o una serie di nomi di file da caricare. Non include un’estensioni di file.
  • mod – Nome file singolo (stringa) da caricare.
  • bundle– Nome file di un bundle di memoria da caricare. Se filename.gzesiste e filenamenon, CTU decomprime automaticamente il file al primo avvio.
  • maps – Dizionario di classe di indirizzi -> file di mappe.
    • Ogni voce deve essere Titlecasedel binario che è la mappa , ad esempio maindiventa Main. Il valore dell’inserzione assume la forma in [0xf00b, "something.map"]cui l’indirizzo è la base di caricamento della mappa.
API

Questa è l’API principale di CTU, utilizzabile da run.py.

  • call(pc, [X0, [X1, ...]], _start=False)– Chiamare una determinata funzione nativa su un thread appena creato. È possibile passare qualsiasi numero di argomenti; Il valore di ritorno è X0 all’uscita. Se _startè impostato su true, X0 è 0 e X1 è l’handle del thread appena creato.
  • debugbreak() – Interrompe il debugger.
  • malloc(size)– assegna lo spazio inbyte all’interno dello spazio di indirizzi dell’ospite.
  • free(addr) – No-op!
  • reg(i, [val])– Legge o assegna un registro in base al numero o il nome ( X0– X31LRSP).
  • pc – Proprietà che consente di leggere / scrivere il valore del PC per il thread corrente.
  • dumpregs() – Visualizza tutti i registri.
  • dumpmem(addr, size, check=False)– Hexdump un blocco di memoria. Se checkè True e memcheck è abilitato, sarai avvisato per le letture di memoria non modificate.
  • readmem(addr, size)writemem(addr, value)– legge o scrive la memoria come stringa di byte.
  • read8/16/32/64(addr)write8/16/32/64(addr, value)– legge o scrive la memoria come un numero intero non firmato di una determinata dimensione.
  • readS8/16/32/64(addr) – Legge la memoria come un numero intero firmato di una determinata dimensione.
  • readstring(addr) – Legge una stringa fino a terminatore nullo o memoria non rimovibile.
  • newHandle(obj)– Assegna un nuovo handle a obje restituisce tale ID handle.
  • closeHandle(handle) – Chiude un handle.
  • map(base, size)– Cartella del blocco di memoria. Se non esiste l’allineamento della pagina, ciò avverrà automaticamente. La memoria verrà annullata se l’esecuzione viene riavviata.
  • unmap(base, size) – Scollegare un blocco di memoria.
  • getmap(addr)– Restituisce la tupla base, sizeper un determinato indirizzo o -1, -1se tale memoria è disattivata.
  • memregions()– Restituisce un generatore che fornisce le tuple di (begin, end, perms)tutte le regioni mappate e non mappate; Le regioni non coordinate hanno perms == -1.
  • hookinsn(insn)– Decoratore che consente di associare un dato valore d’istruzione (come intero). La funzione decorata dovrebbe avere argomenti ctu, addrdove addr è l’indirizzo dell’istruzione. Il gancio accade prima dell’esecuzione.
  • hookfetch(addr)– Decoratore che consente di associare un dato indirizzo di istruzione prima dell’esecuzione. La funzione decorata non assume argomenti.
  • hookread(addr)hookwrite(addr)– Decoratori che consentono di agganciare la memoria in lettura / scrittura ad un indirizzo. Decoratore dovrebbe avere argomenti ctu, sizectu, addr, size, valuerispettivamente. I ganci di lettura possono restituire un valore di sostituzione. Se writehook restituisce non NoneFalse, viene eliminato.
  • replaceFunction(addr)– Decoratore che consente di sostituire una funzione nel codice nativo nell’indirizzo indicato. La funzione decorata ottiene ctucome primo argomento, ma può prendere qualsiasi numero di argomenti al di là di esso (mappati automaticamente da X0 … X30) e restituire un numero con qualsiasi tipo di valore (mappato automaticamente a X0 … X30). La funzione originale non verrà eseguita.
IPC Client

Sysmodules espone l’interfaccia IPC sulla rete. I dettagli di quel protocollo sono documentati in wireprotocol.txt, ma è incluso un client Python.

L’utilizzo di esempio è in skeletonSample/client.py. Si crea un Clientoggetto e si connette a un’istanza CTU, quindi crea e invia IPCMessageavanti e indietro.

Riferimento del debugger

Il debugger in CTU è approssimativamente basato su gdb ma ha alcune differenze chiave che veramente irritano i fan di GDB.

  • exit — Uscita.
  • s/start – Avviare o riavviare l’esecuzione.
  • t/trace (i/instruction | b/block | f/function | m/memory) – Toglie il tracciamento.
  • mc/memcheck – Consente di attivare il monitoraggio delle violazioni di accesso alla memoria.
  • b/break [name]– Senza name, elenca i punti di interruzione; Altrimenti effettua la commutazione nel punto di interruzione per il nome o l’indirizzo del simbolo.
  • bt – Stampare lo stack di chiamata.
  • sym <name> – Stampare l’indirizzo di un dato simbolo.
  • c/continue – Continua l’esecuzione.
  • n/next — Singolo passo.
  • r/reg/regs [reg [value]]
    • Nessun parametro: visualizza tutti i registri.
    • Parametro Reg: visualizza un registro.
    • Reg e valore: assegna un valore (sempre esagono o un nome di simbolo) a un registro.
  • x/exec <code> – Valuta una determinata linea di C.
  • dump <address> [size=0x100]– Depone i sizebyte della memoria ad un indirizzo. Se l’indirizzo prende la forma *register(ad esempio *X1), verrà utilizzato il valore di quel registro.
  • save <address> <size> <fn>– Scrive i sizebyte della memoria in un file. Se l’indirizzo o la dimensione assumono la forma *register(ad esempio *X1), verrà utilizzato il valore di quel registro.
  • ad – Toggle di visualizzazione dell’ indirizzo
  • w/watch [expression]– Interrompe quando l’espressione viene valutata come true. Senza un’espressione, elenca gli orologi esistenti.
  • mr/memregions – Mostra regioni di memoria mappate
Fonte:

Github

Ti è piaciuta la notizia? Supporta theheroGAC su Patreon!

theheroGAC

Nato negli anni 80 con la passione dei videogiochi e delle console.Il mio primo home computer è l'Amiga 600 regalato a 10 anni.Amo aiutare le persone in difficoltà e scrivere notizie sulle console.Studio all'università e il sito Games And Consoles è la mia passione.Per gli amici mi potete chiamare Ciccio

Ti potrebbe anche interessare

Rispondi