Si può "fermare" un programma C dall'essere decodificato? [duplicare]

17

Sono sicuro che molte delle lingue di medio-alto livello possono essere decodificate. Ma se un programma C può essere decodificato e trasformato in codice sorgente modificabile, come posso scoraggiare una cosa del genere?

    
posta Snazzy Sanoj 07.03.2015 - 19:25
fonte

9 risposte

4

Se qualcuno può osservare il programma in funzione, può eseguirne il reverse engineering. Anche se potresti in qualche modo impedire all'utente di accedere agli interni del programma, possono eseguire reverse engineering black-box per costruire un modello di come il programma reagisce ai vari input.

    
risposta data 08.03.2015 - 02:01
fonte
35

È impossibile impedire il reverse engineering per qualsiasi programma eseguito sul tuo computer. Ma puoi fare dei passaggi che rendono più difficile ...

I linguaggi di programmazione come Java e .NET sono banali per ricreare il codice sorgente umano, poiché sono codificati in byte. Significa che il linguaggio di programmazione è compilato in una serie di token interpretati da un motore di runtime o "macchina virtuale". Ciò rende la compilazione inversa un'attività realizzabile.

A causa di questa facilità di ottenere il codice sorgente C # per qualsiasi libreria .NET, ci sono diversi trucchi spesso fatti per renderlo più difficile. Un approccio è riscrivere il codice in modo che tutti i nomi di classi e metodi non siano significativi e simili. Ciò rende il codice sorgente C # disponibile al 100%, ma in genere non comprensibile per un essere umano per capire cosa sta succedendo nel codice.

Il passo successivo è rendere più difficile la creazione di una versione crittografata della libreria, con codice wrapper che decrittografa la libreria di codici byte in memoria. Ciò rende più difficile, ma non c'è nulla che impedisca a una persona determinata di utilizzare un debugger dell'assemblatore per passare attraverso il processo di decrittografia fino a quando il codice byte .NET è stato decompilato e quindi facendo un dump della memoria per ottenere i codici byte.

C ha un enorme vantaggio nella protezione del codice sorgente, in quanto la sorgente è compilata in codice macchina. Questo non è infallibile però. Per consentire agli sviluppatori di scorrere il loro codice, il compilatore avrà opzioni che impediscono alle ottimizzazioni di riorganizzare il codice e, peggio ancora, spesso aggiungono ulteriori dati all'eseguibile per fornire contesto al codice che sarebbe utilizzabile per la decompilazione.

Laddove il codice C non è banale, compilato con le ottimizzazioni attivate e privato di tutti i dati di debug, cercare di ricreare codice comprensibile è oltre lo sforzo / la ricompensa per la maggior parte delle persone.

Detto questo, ho imparato a programmare in assembler da bambino passando per il codice del caricatore di assemblatori su ZX Spectrums progettato per rendere più difficile per le persone copiare e / o modificare il programma per darti vite infinite.

Trascorrere tre giorni in lunghe vacanze estive a passare attraverso il codice che stava transcodificando il set di byte memorizzati sul nastro nel codice di caricamento del nastro modificato che effettivamente caricava il gioco mi sembrava un buon uso del mio tempo, e ho iniziato ho una lunga carriera come sviluppatore di software da adulto.

    
risposta data 07.03.2015 - 19:54
fonte
15

Qualsiasi programma può essere decodificato, a causa del principio molto semplice che qualsiasi cosa che un computer può eseguire deve essere in un formato in cui una persona che comprende il codice macchina può leggere. (Con gli strumenti adeguati, ovviamente.)

La vera domanda è: quanto è facile da decodificare? C è banale da decompilare; Ho visto un codice C sorprendentemente pulito generato da strumenti di decompilazione. Ma poiché C non ha gli stessi metadati ricchi dei linguaggi gestiti, si perdono molte informazioni utili, come i nomi di variabili e tipi di dati, che aiutano nel compito del reverse engineering. (Ancora una volta, la maggior parte dei sistemi di codice gestito ha uno strumento "offuscatore" disponibile che manipola i metadati per rendere tali compiti più difficili per il reverse engineer, quindi la differenza potrebbe non essere necessariamente così grande.)

    
risposta data 07.03.2015 - 19:40
fonte
11

Molte tecniche anti-debug possono essere utilizzate per rendere il reverse engineering un compito arduo, ma non impossibile.

Gli autori di malware li usano regolarmente, e molti sono applicabili a qualsiasi codice macchina nativo, incluso quello compilato da C.

Un semplice esempio che è stato molto popolare nei primi anni è stato l'inserimento di migliaia di punti di interruzione per rendere noioso l'esecuzione di un determinato punto di codice, poiché è necessario rimuovere tutti quei punti di interruzione.

Altri metodi sono il polimorfismo, il codice auto-modificante e la decrittografia / crittografia run-time o gli hack basati sulla cache per nascondere i percorsi di esecuzione eseguiti il più a lungo possibile.

Inoltre, puoi utilizzare tecniche di offuscamento tradizionali come la creazione di codice di esca, la costruzione di valori opachi, salti extra e pseudo-condizioni per rendere più difficile la comprensione del codice.

Funziona per qualsiasi linguaggio, non solo gestito .NET, Java o PHP, dove il reverse engineering è normalmente banale, ma anche per C / C ++.

Gli autori di malware forniscono i migliori esempi, ad es. Rombertik analizzato da Cisco .

Indurire contro il revenging è di solito un problema economico:

  • quanto è facile aggiungere protezioni
  • quanto ostacola la manutenzione
  • in che modo influisce sull'uso e le prestazioni delle risorse (ad esempio memoria, utilizzo della CPU),
  • quanto è compatibile (funziona sempre e ovunque, può attivare un antivirus),
  • quanto è difficile romperli

Questo termina con la domanda: Ne vale la pena?

I risparmi sono superiori alle spese?
I costi per rompere più dei potenziali guadagni di rev-engineering?

Esistono degli offuscatori disponibili per le lingue popolari per automatizzare l'aggiunta di misure di protezione ai tuoi programmi, ma la loro qualità varia.

    
risposta data 08.03.2015 - 02:32
fonte
4

Puoi decodificare qualsiasi programma, il risultato non sarà il codice sorgente originale con commenti, nomi di variabili descrittive, struttura ecc. ma la sua funzionalità sarà la stessa. Non puoi impedirlo, puoi renderlo più difficile ma non puoi impedirlo perché alla fine del giorno saranno le istruzioni che la CPU comprenderà e quindi potrai interpretare. Il modo migliore in cui IMHO impedisce la copia di reverse engineering / pirata è di aggiornare il programma frequentemente aggiungendo più funzionalità, quindi si raggiungerà un punto in cui lo sforzo di decodificare è troppo complicato rispetto all'acquisto / scrittura da soli.

    
risposta data 08.03.2015 - 00:14
fonte
3

Non permettere ad altri di accedere al programma. Eseguilo in un server * sicuro che controlli e lascia che gli utenti si interfacciano con esso solo fornendo l'input sulla rete e ricevendo indietro l'output.

Vedi link

Lo svantaggio è che ora devi gestire il server.

* La sicurezza di un server è tutt'altro che banale. Per una sicurezza veramente elevata, assumi un professionista.

    
risposta data 08.03.2015 - 18:54
fonte
3

Come le altre risposte dicono, se riesci a vedere il file binario puoi decodificare la funzione del programma, anche se probabilmente con difficoltà. Il vantaggio è quindi quello di impedire all'utente di accedere al file binario.

I vecchi sistemi arcade facevano ciò memorizzando il programma oi parametri critici nella RAM con batteria tampone collegata agli interruttori antimanomissione. Apri il caso e il programma evapora. I moderni iPhone usano ARM "TrustZone" per caricare un microkernel dal bootrom crittografato con accesso hardware privilegiato; questo è usato per il sensore di impronte digitali e alcune delle funzioni di pagamento.

(Ovviamente, questo significa che il telefono potrebbe essere compromesso in fabbrica senza che l'utente possa rilevarlo o recuperarlo ..)

Io stesso ho riportato un paio di bug nel firmware del produttore dallo smontaggio di ARM e ho considerato quanto lavoro potrebbe essere per scrivere un programma di decompilazione dell'assistente.

    
risposta data 08.03.2015 - 21:54
fonte
2

Semplice, almeno negli Stati Uniti Hai appena inserito una clausola anti-reverse engineering nell'EULA del programma e minaccia di citare in giudizio i pantaloni di chiunque la rompa (non è uno scherzo, il DMCA ti consente di farlo in questo modo ).

    
risposta data 08.03.2015 - 09:56
fonte
2

Per rendere quasi impossibile il reverse engineering di C? È possibile - scrivere la tua C in modo tale che l'intera logica dipenda dall'ingresso AT RUNTIME (forse ora devi proteggere i tuoi input, che mantengono il segreto della tua logica nel programma C). Quindi leggere il codice sorgente C non ha alcun significato.

Come? Un modo: usare molti puntatori di funzioni. Quindi leggendo:

a->function1();
c->function2();

impossibile indovinare cosa fa la funzione1 (), in quanto è un puntatore assegnato in modo dinamico assegnato solo durante il runtime, a seconda dell'input.

Se crei molte funzioni di base come sopra, e poi costruisci dinamicamente la tua logica disponendo il token di input, è possibile implementare qualsiasi logica.

Nel linguaggio assembly, l'equivalente analogo è chiamato "Return-oriented programming" - dove puoi costruire quasi tutte le logiche possibili usando il numero esadecimale accuratamente selezionato dal programma originale:

link

In un certo senso, quello che sto proponendo è qualcosa come un "interprete": ad esempio, un programma interprete javascript stesso, scritto in C, può comportarsi in molti modi diversi, a seconda del programma "javascript" come input. Quindi non ha senso rovesciare l'interprete stesso - poiché il programma di input "javascript" è l'ultima macchina logica.

Aggiornamento:

Supponendo di avere l'input, a RE in modo dinamico può essere anche molto difficile, perché se si usano i breakpoint del software (supponendo 0xcc strumentato nel codice) quindi con il self-checksum dell'area del codice, più il checksum di molti piccoli selezionati casualmente bloccare e confrontare il checksum con il codice originale non tratteggiato, è possibile rilevare facilmente qualsiasi punto di interruzione software. E se usi il breakpoint dell'hardware? beh, l'analisi dei tempi tra qualsiasi pezzo di codice selezionato casualmente rileverà facilmente che qualcuno sta cercando di analizzare il codice. E se si utilizza un emulatore software come Boch / pintool / Intel branch tracing che non utilizza il breakpoint del software, e può ingannare l'orologio abbastanza da bypassare l'analisi del tempo, beh, è possibile farlo. Ma forse la quantità di dati da analizzare può ammontare a molti concerti di dati. Non facile.

Ma per essere in grado di svolgere i due compiti sopra descritti, non è più C - devi prendere l'output binario e strumentarlo con i codici di checksum, oltre al codice di analisi temporale tra due punti qualsiasi - tutti inseriti casualmente come bene.

Un esempio di binario reale che è difficile da analizzare (o preso anni e grandi aziende anti-virus stanno ancora cercando di capirlo): Stuxnet. E questo binario (non è sicuro?) Non si connette a Internet, funziona da solo.

    
risposta data 08.03.2015 - 16:44
fonte

Leggi altre domande sui tag