Proteggere il file eseguibile dal reverse engineering?


210

Ho riflettuto su come proteggere il mio codice C / C ++ dallo smontaggio e dal reverse engineering. Normalmente non perdonerei mai questo comportamento nel mio codice; tuttavia l'attuale protocollo su cui sto lavorando non deve mai essere ispezionato o comprensibile, per la sicurezza di varie persone.

Ora questo è un nuovo argomento per me e Internet non è davvero pieno di risorse per la prevenzione contro il reverse engineering, ma piuttosto descrive tonnellate di informazioni su come effettuare il reverse engineering

Alcune delle cose che ho pensato finora sono:

  • Iniezione di codice (chiamata delle funzioni fittizie prima e dopo le effettive chiamate di funzione)
  • Codice obfustication (manipola lo smontaggio del binario)
  • Scrivi le mie routine di avvio (più difficile da associare ai debugger)

    void startup();  
    int _start()   
    {  
        startup( );  
        exit   (0)   
    }  
    void startup()  
    {  
        /* code here */  
    }
  • Verifica del runtime per debugger (e forza l'uscita se rilevata)

  • Trampolini funzionali

     void trampoline(void (*fnptr)(), bool ping = false)  
     {  
       if(ping)  
         fnptr();  
       else  
         trampoline(fnptr, true);  
     }
  • Allocazioni e deallocazioni inutili (lo stack cambia molto)

  • Chiamate e trampolini fittizi inutili (tonnellate di salti in uscita dallo smontaggio)
  • Tonnellate di colata (per smontaggio offuscato)

Voglio dire, queste sono alcune delle cose a cui ho pensato, ma possono essere tutte risolte e capite dagli analisti del codice, dato il giusto periodo di tempo. C'è qualcos'altro che ho di alternativo?


172
"tuttavia l'attuale protocollo su cui sto lavorando non deve mai essere ispezionato o comprensibile, per la sicurezza di varie persone." -- buona fortuna.
Ambra

62
Puoi rendere la tua applicazione difficile da decodificare. Non puoi renderlo impossibile, non fino a quando l'altro ragazzo ha una parte sostanziale dei tuoi pezzi nelle loro mani. Attenti a garantire la massima sicurezza, soprattutto se sono in gioco delle vite: non è possibile fornire risultati.
Michael Petrotta,

127
Se il tuo computer è in grado di capire il codice, anche una persona.
Razze di leggerezza in orbita il

78
Rendi il codice Open Source e nessuno lo decodificherà.
utente sconosciuto il

28
"La sicurezza per oscurità non ha mai funzionato."
bot47,

Risposte:


151

Quello che ha detto Amber è esattamente giusto. Puoi rendere più difficile il reverse engineering, ma non puoi mai prevenirlo. Non dovresti mai fidarti della "sicurezza" che si basa sulla prevenzione del reverse engineering .

Detto questo, le migliori tecniche di anti-reverse engineering che ho visto non si concentravano sull'offuscamento del codice, ma piuttosto sulla rottura degli strumenti che le persone normalmente usano per capire come funziona il codice. Trovare modi creativi per rompere disassemblatori, debugger, ecc. È probabilmente più efficace e anche più intellettualmente soddisfacente rispetto alla semplice generazione di risme di orribili codici spaghetti. Questo non fa nulla per bloccare un determinato attaccante, ma aumenta la probabilità che J Random Cracker si allontani e lavori invece su qualcosa di più semplice.


14
Lo capisco e ho letto alcuni articoli sulla sicurezza di Skype spiegati e sto riflettendo sulle stesse idee che Skype ha già provato come metodo per non prevenire ma piuttosto proteggere il mio protocollo. Qualcosa che si è dimostrato abbastanza degno date le ovvie circostanze per Skype.
graphitemaster,

8
Skype è in realtà il primo esempio che mi è venuto in mente, quindi sono contento che tu stia già cercando di emulare i loro metodi.
Ricket,

176

ma possono essere tutti risolti o capiti dagli analisti del codice con il giusto lasso di tempo.

Se dai alle persone un programma che sono in grado di eseguire, allora saranno anche in grado di decodificarlo dato il tempo sufficiente. Questa è la natura dei programmi. Non appena il file binario è disponibile per qualcuno che vuole decifrarlo, non è possibile impedire l'eventuale retroingegnerizzazione. Dopotutto, il computer deve essere in grado di decifrarlo per eseguirlo e un essere umano è semplicemente un computer più lento.


113
+1. Leggi i giorni di gloria della protezione dalla copia sull'Apple II, la guerra sempre crescente tra gli offuscatori e i cracker, i trucchi folli con il motore passo-passo del floppy disk e le istruzioni non documentate 6502 e così via ... E poi piangi dormi, perché non hai intenzione di implementare qualcosa di così elaborato e alla fine si sono tutti rotti.
Nemo,

2
più facile da usare un simulatore e ottenere una migliore visibilità rispetto a provare a decodificare visivamente o con un disassemblatore. Se la sicurezza non è integrata nell'hardware che stai utilizzando, penso che il mondo stia facendo una media di circa due giorni a due settimane per decodificare e sconfiggere praticamente tutto ciò che viene fuori. Se ti occorrono più di due giorni per creare e implementare questo, hai trascorso troppo tempo.
old_timer,

5
L'unico DRM ragionevolmente funzionante oggi è la combinazione di una chiave e un server Internet che verifica che solo un'istanza della chiave sia attiva su un timem.
Thorbjørn Ravn Andersen,

2
@Rotsor: il computer non può capirlo perché non siamo riusciti a ridurre questo tipo di intelligenza a un algoritmo (ancora), non perché esiste una sorta di barriera fisica o tecnologica in atto. L'umano può capirlo perché può fare qualsiasi cosa il computer (anche se più lentamente) e la ragione .
Adam Robinson,

3
A quel punto qualcuno proverà a decodificare il computer, a meno che non sia disponibile solo in un ambiente che controlli.
Ambra

41

Safe Net Sentinel (precedentemente Aladdin). Avvertenze: la loro API fa schifo, la documentazione fa schifo ed entrambi sono fantastici rispetto ai loro strumenti SDK.

Ho usato il loro metodo di protezione hardware ( Sentinel HASP HL ) per molti anni. Richiede un portachiavi USB proprietario che funge da "licenza" per il software. Il loro SDK crittografa e offusca il tuo eseguibile e le tue librerie e ti consente di associare diverse funzionalità della tua applicazione a funzionalità inserite nella chiave. Senza una chiave USB fornita e attivata dal licenziante, il software non può decrittografare e quindi non può essere eseguito. La chiave utilizza persino un protocollo di comunicazione USB personalizzato (al di fuori del mio regno di conoscenza, non sono un tipo di driver di dispositivo) per rendere difficile la creazione di una chiave virtuale o manomettere la comunicazione tra il wrapper di runtime e la chiave. Il loro SDK non è molto intuitivo per gli sviluppatori ed è abbastanza doloroso integrarsi aggiungendo protezione con un processo di compilazione automatizzato (ma possibile).

Prima di implementare la protezione HASP HL, c'erano 7 pirati noti che avevano rimosso le "protezioni" dotfuscator dal prodotto. Abbiamo aggiunto la protezione HASP contemporaneamente a un importante aggiornamento del software, che esegue alcuni pesanti calcoli sul video in tempo reale. Come meglio posso dire dalla profilazione e dal benchmarking, la protezione HASP HL ​​ha solo rallentato i calcoli intensivi di circa il 3%. Da quando il software è stato rilasciato circa 5 anni fa, non è stato trovato un nuovo pirata del prodotto. Il software che protegge è molto richiesto nel suo segmento di mercato e il cliente è a conoscenza di numerosi concorrenti che stanno attivamente cercando di decodificare (senza successo finora). Sappiamo che hanno cercato di chiedere aiuto ad alcuni gruppi in Russia che pubblicizzano un servizio per violare la protezione del software,

Recentemente abbiamo provato la loro soluzione di licenza software (HASP SL) su un progetto più piccolo, che era abbastanza semplice da funzionare se hai già familiarità con il prodotto HL. Sembra funzionare; non sono stati segnalati episodi di pirateria, ma questo prodotto è molto più richiesto.

Naturalmente, nessuna protezione può essere perfetta. Se qualcuno è sufficientemente motivato e ha soldi seri da bruciare, sono sicuro che le protezioni offerte da HASP potrebbero essere eluse.


19
Nota del moderatore: i commenti sotto questa risposta sono stati rimossi a causa del divagare nel rumore antagonistico.
Tim Post

2
+1 per esperienza, ma vorrei ribadire che non è perfetto. Maya (suite 3D) ha usato un dongle hardware (non sono sicuro che fosse HASP), che non ha scoraggiato i pirati per molto tempo. Quando c'è volontà c'è un modo.
Robert Fraser,

1
AutoCAD utilizza un sistema simile, che è stato crackato numerose volte. HASP e altri simili manterranno le persone oneste e prevengono la pirateria informale. Se stai costruendo il prossimo prodotto di design da molti miliardi di dollari, avrai sempre i cracker con cui fare i conti. Si tratta di rendimenti decrescenti: quante ore di sforzo vale la pena decifrare la protezione del software rispetto al solo pagamento.
RyanR,

6
Voglio anche entrare dal punto di vista di qualcuno che ha usato il software sicuro HASP. Gli HASP sono un dolore reale nel culo per l'utente finale . Ho avuto a che fare con un Dallas iButton e un Aladdin HASP, ed entrambi erano davvero difettosi, e il software ha smesso di funzionare in modo casuale, richiedendo la disconnessione e la riconnessione dell'HASP.
Nome falso

4
Inoltre, vale la pena notare che le misure di sicurezza HASP non sono necessariamente più sicure dell'offuscamento del codice - sicuramente richiedono una metodologia diversa per decodificare, ma è molto possibile invertirle - Vedi: flylogic.net/blog/?p=14 flylogic.net/blog/?p=16 flylogic.net/blog/?p=11
Nome falso

22

I migliori trucchi anti-disassemblatore, in particolare sui set di istruzioni di lunghezza variabile delle parole, sono nel codice assemblatore / macchina, non C.

CLC
BCC over
.byte 0x09
over:

Il disassemblatore deve risolvere il problema che una destinazione di ramo è il secondo byte in un'istruzione multibyte. Tuttavia, un simulatore di set di istruzioni non avrà alcun problema. La diramazione verso indirizzi calcolati, che puoi causare da C, rende anche impossibile lo smontaggio difficile. Il simulatore del set di istruzioni non avrà alcun problema. L'uso di un simulatore per ordinare le destinazioni delle filiali per te può aiutare il processo di smontaggio. Il codice compilato è relativamente pulito e facile per un disassemblatore. Quindi penso che sia necessario un po 'di assemblaggio.

Penso che sia stato quasi all'inizio dello Zen of Assembly Language di Michael Abrash in cui ha mostrato un semplice trucco anti-disassemblatore e anti-debugger. L'8088/6 aveva una coda di prefetch. Quello che hai fatto è stato avere un'istruzione che ha modificato l'istruzione successiva o una coppia in anticipo. Se il passo singolo ha eseguito l'istruzione modificata, se il simulatore del set di istruzioni non ha simulato completamente l'hardware, è stata eseguita l'istruzione modificata. Sull'hardware reale in esecuzione normalmente l'istruzione reale si troverebbe già nella coda e la posizione della memoria modificata non causerebbe alcun danno fino a quando non eseguirai nuovamente quella stringa di istruzioni. Probabilmente potresti ancora usare un trucco come questo oggi, poiché i processori pipeline recuperano le istruzioni successive. Oppure, se si sa che l'hardware ha un'istruzione e una cache di dati separate, è possibile modificare un numero di byte in anticipo se si allinea correttamente questo codice nella riga della cache, il byte modificato non verrà scritto attraverso la cache delle istruzioni ma la cache dei dati e un simulatore del set di istruzioni che non aveva i simulatori di cache corretti non sarebbe stato eseguito correttamente. Penso che solo le soluzioni software non ti porteranno molto lontano.

Quanto sopra è vecchio e ben noto, non so abbastanza sugli strumenti attuali per sapere se funzionano già intorno a tali cose. Il codice automodificante può / farà scattare il debugger, ma l'umano può / si restringerà sul problema e quindi vedrà il codice automodificante e aggirerà il problema.

In passato gli hacker impiegavano circa 18 mesi per risolvere qualcosa, ad esempio i DVD. Ora sono in media da 2 giorni a 2 settimane (se motivati) (raggio blu, iPhone, ecc.). Ciò significa per me se trascorro più di qualche giorno in sicurezza, probabilmente sto sprecando il mio tempo. L'unica vera sicurezza che otterrai è attraverso l'hardware (ad esempio le tue istruzioni sono crittografate e solo il core del processore all'interno del chip si decodifica appena prima dell'esecuzione, in modo tale da non poter esporre le istruzioni decriptate). Ciò potrebbe comprarti mesi anziché giorni.

Leggi anche il libro di Kevin Mitnick The Art of Deception. Una persona del genere potrebbe alzare un telefono e fare in modo che tu o un collega distribuiate i segreti al sistema pensando che si tratti di un manager o di un altro collega o ingegnere hardware in un'altra parte dell'azienda. E la tua sicurezza è saltata. La sicurezza non riguarda solo la gestione della tecnologia, ma anche la gestione degli umani.


1
Inoltre, non è necessario avere accesso al codice sorgente (o anche al codice sorgente disassemblato) per trovare una falla nella sicurezza. Potrebbe essere per caso o usando il fatto che la maggior parte dei buchi provengono dagli stessi problemi nel codice (come gli overflow del buffer).
asmeurer,

2
Ci sono grossi problemi con il codice che si modifica da solo. La maggior parte dei sistemi operativi / hardware moderni non ti consente di farlo senza privilegi molto elevati, ci possono essere problemi di cache e il codice non è thread-safe.
Martin James

1
Con i moderni processori x86, trucchi come questi sono spesso dannosi per le prestazioni. L'uso della stessa posizione di memoria come parte di più di un'istruzione probabilmente ha un effetto simile a un ramo mal previsto. Il codice automodificante fa sì che il processore elimini le righe della cache per mantenere la coerenza tra l'istruzione e le cache dei dati (se si esegue il codice modificato molto più spesso di quanto lo si modifichi, potrebbe essere comunque una vittoria).
jilles,

2
Mi sono imbattuto in questo 20 anni fa. Ci sono voluti quasi mezz'ora per capire cosa è successo. Non molto buono se hai bisogno di una protezione più lunga.
Bo Persson,

1
"l'istruzione reale sarebbe già nella coda e la posizione della memoria modificata non causerebbe alcun danno" Fino a quando non si verifica un interruzione nel mezzo, svuotando la pipeline dell'istruzione e rendendo visibile il nuovo codice. Ora la tua offuscamento ha causato un bug per i tuoi utenti legittimi.
Ben Voigt,

21

Prendi, ad esempio, l' algoritmo AES . È un algoritmo molto, molto pubblico ed è MOLTO sicuro. Perché? Due motivi: è stato esaminato da molte persone intelligenti e la parte "segreta" non è l'algoritmo stesso: la parte segreta è la chiave che è uno degli input dell'algoritmo. È un approccio molto migliore per progettare il protocollo con un "segreto" generato che è al di fuori del codice, piuttosto che rendere segreto il codice stesso. Il codice può sempre essere interpretato, qualunque cosa tu faccia, e (idealmente) il segreto generato può essere messo a repentaglio solo da un massiccio approccio alla forza bruta o attraverso il furto.

Penso che una domanda interessante sia " Perché vuoi offuscare il tuo codice?" Vuoi rendere difficile per gli aggressori violare i tuoi algoritmi? Per rendere più difficile per loro trovare bug sfruttabili nel tuo codice? Non sarebbe necessario offuscare il codice se il codice non fosse crackabile in primo luogo. La radice del problema è il software crackabile. Risolvi la radice del tuo problema, non solo offuscarlo.

Inoltre, più confonderai il tuo codice, più difficile sarà per TE trovare bug di sicurezza. Sì, sarà difficile per gli hacker, ma devi anche trovare bug. Il codice dovrebbe essere facile da mantenere tra anni, e persino un codice chiaro ben scritto può essere difficile da mantenere. Non peggiorare le cose.


3
+1 per il buon senso: perché renderlo più difficile per te quando potresti semplicemente progettare un sistema migliore.
Necrolis,

1
Come dico sempre, se si tiene tutto sul lato server, è più sicuro
liamzebedee,

20

Rendere il codice difficile da decodificare è chiamato offuscamento del codice.

La maggior parte delle tecniche che menzioni sono abbastanza facili da aggirare. Si concentrano sull'aggiunta di un codice inutile. Ma il codice inutile è facile da rilevare e rimuovere, lasciandoti con un programma pulito.

Per un'efficace offuscamento, è necessario subordinare il comportamento del programma ai bit inutili in esecuzione. Ad esempio, anziché fare questo:

a = useless_computation();
a = 42;

Fai questo:

a = complicated_computation_that_uses_many_inputs_but_always_returns_42();

O invece di fare questo:

if (running_under_a_debugger()) abort();
a = 42;

Fai questo (dove running_under_a_debuggernon dovrebbe essere facilmente identificabile come una funzione che verifica se il codice è in esecuzione in un debugger - dovrebbe mescolare calcoli utili con il rilevamento del debugger):

a = 42 - running_under_a_debugger();

L'offuscamento efficace non è qualcosa che puoi fare puramente in fase di compilazione. Qualunque cosa il compilatore possa fare, un decompilatore può fare. Certo, puoi aumentare l'onere per i decompilatori, ma non andrà lontano. Tecniche di offuscamento efficaci, nella misura in cui esistono, prevedono la scrittura di fonti offuscate dal primo giorno. Rendi il tuo codice auto-modificante. Spargi il tuo codice con salti calcolati, derivati ​​da un gran numero di input. Ad esempio, invece di una semplice chiamata

some_function();

fai questo, dove ti capita di conoscere l'esatto layout previsto dei bit in some_data_structure:

goto (md5sum(&some_data_structure, 42) & 0xffffffff) + MAGIC_CONSTANT;

Se sei serio riguardo all'offuscamento, aggiungi diversi mesi alla tua pianificazione; l'offuscamento non costa poco. E considera che il modo migliore per evitare la retroingegnerizzazione del tuo codice da parte delle persone è renderlo inutile in modo che non si preoccupino. È una semplice considerazione economica: decodificheranno se il valore per loro è maggiore del costo; ma aumentando il loro costo aumenta anche molto il costo, quindi prova a ridurne il valore.

Ora che ti ho detto che l' offuscamento è duro e costoso, ti dirò comunque che non fa per te . Scrivi

l'attuale protocollo su cui sto lavorando non deve mai essere ispezionato o comprensibile, per la sicurezza di varie persone

Ciò solleva una bandiera rossa. È la sicurezza per oscurità , che ha un record molto scarso. Se la sicurezza del protocollo dipende da persone che non conoscono il protocollo, hai già perso .

Lettura consigliata:


1
@Gilles, questa è la tua affermazione, che è molto forte, quindi l'onere della prova ricade su di te. Tuttavia, fornirò un semplice esempio: 2+2può essere semplificato dal compilatore 4, ma il decompilatore non può riportarlo a 2+2(e se fosse effettivamente 1+3?).
Rotsor,

7
@Rotsor 4e 2+2sono equivalentemente osservazionali, quindi sono gli stessi per questo scopo, vale a dire per capire cosa sta facendo il programma. Sì, certo, il decompilatore non può ricostruire il codice sorgente, ma questo è irrilevante. Queste domande e risposte riguardano la ricostruzione del comportamento (cioè l'algoritmo e più precisamente un protocollo).
Gilles 'SO- smetti di essere malvagio' il

1
Non devi fare nulla per ricostruire il comportamento. Hai già il programma! Ciò di cui di solito hai bisogno è capire il protocollo e cambiare qualcosa in esso (come sostituire un 2 in 2+2con 3 o sostituire +un con a *).
Rotsor,

1
Se consideri tutti i programmi equivalenti al comportamento allo stesso modo, allora sì, il compilatore non può fare nulla perché esegue solo una trasformazione di indentità. Anche il decompilatore è inutile, poiché è di nuovo una trasformazione dell'identità. Se non lo fai, tuttavia 2+2-> 4è un esempio valido di trasformazione non reversibile eseguita dal compilatore. Sia che renda la comprensione più facile o più difficile è un argomento separato.
Rotsor,

2
@Gilles Non posso estendere la tua analogia con la mela perché non riesco a immaginare una mela strutturalmente diversa, ma comportamentalmente equivalente. :)
Rotsor,

13

Molte volte, la paura che il tuo prodotto venga retroingegnerizzato è fuori luogo. Sì, può essere retroingegnerizzato; ma diventerà così famoso in un breve periodo di tempo, che gli hacker troveranno la pena di invertire engg. vero? (questo lavoro non è una piccola attività temporale, per sostanziali righe di codice).

Se diventa davvero un guadagno, allora dovresti aver raccolto abbastanza soldi per proteggerlo usando i modi legali come, brevetto e / o copyright .

IMHO, prendi le precauzioni di base che prenderai e rilascialo. Se diventa un punto di reverse engineering che significa che hai fatto davvero un buon lavoro, tu stesso troverai modi migliori per superarlo. In bocca al lupo.


1
Voglio dire, questa è una risposta valida e applicabile, ma la linea che traccia tra protezione e guadagno di un paio di milioni per avere altri che proteggono il tuo prodotto per te è una linea davvero lunga.
graphitemaster,

12

Leggi http://en.wikipedia.org/wiki/Security_by_obscurity#Arguments_against . Sono sicuro che altri potrebbero probabilmente anche fornire una migliore fonte del perché la sicurezza attraverso l'oscurità è una cosa negativa.

Dovrebbe essere del tutto possibile, usando le moderne tecniche crittografiche, avere il tuo sistema aperto (non sto dicendo che dovrebbe essere aperto, solo che potrebbe essere), e avere comunque totale sicurezza, purché l'algoritmo crittografico non lo faccia avere un buco (probabilmente non se ne scegli uno buono), le tue chiavi / password private rimangono private e non hai buchi di sicurezza nel tuo codice ( questo è ciò di cui dovresti preoccuparti).


2
Sono d'accordo con questo. Penso che potresti avere un problema concettuale o di progettazione. Esiste un analogo con una soluzione di coppia di chiavi privata-pubblica? Non divulgare mai la chiave privata, rimane con il proprietario il cui client sicuro la elabora. Riesci a mantenere il codice sicuro fuori dal computer e a restituire i risultati all'utente?
Dizzley,

8

Da luglio 2013, c'è un rinnovato interesse per l'offuscamento crittograficamente robusto (sotto forma di indistinguibilità dell'offuscamento ) che sembra essere scaturito dalla ricerca originale di Amit Sahai .

Puoi trovare alcune informazioni distillate in questo articolo della rivista Quanta e in quell'articolo IEEE Spectrum .

Attualmente la quantità di risorse necessarie per utilizzare questa tecnica la rende poco pratica, ma il consenso di AFAICT è piuttosto ottimista per il futuro.

Lo dico in modo molto casuale, ma per tutti coloro che sono stati abituati a respingere istintivamente la tecnologia dell'offuscamento: è diverso. Se ha dimostrato di funzionare davvero e reso pratico, questo è davvero importante, e non solo per l'offuscamento.


7

Per informarti, leggi la letteratura accademica sull'offuscamento del codice . Christian Collberg dell'Università dell'Arizona è un rispettabile studioso in questo campo; Anche Salil Vadhan dell'Università di Harvard ha fatto un buon lavoro.

Sono dietro a questa letteratura, ma l'idea essenziale di cui sono a conoscenza è che non puoi impedire a un utente malintenzionato di vedere il codice che eseguirai, ma puoi circondarlo con codice che non viene eseguito e costa un tempo esponenziale dell'attaccante (usando le tecniche più conosciute) per scoprire quali frammenti del tuo codice vengono eseguiti e quali no.


7

C'è un recente documento chiamato " Offuscamento del programma e programmi unici ". Se sei davvero serio nel proteggere la tua applicazione. Il documento in generale ruota attorno ai risultati teorici dell'impossibilità mediante l'uso di hardware semplice e universale.

Se non puoi permetterti di richiedere hardware aggiuntivo, allora c'è anche un altro documento che fornisce l'offuscamento teoricamente migliore "Sull'offuscamento migliore ", tra tutti i programmi con le stesse funzionalità e stesse dimensioni. Tuttavia, l'articolo mostra che la teoria dell'informazione migliore possibile implica un crollo della gerarchia polinomiale.

Questi documenti dovrebbero almeno darti sufficienti indicazioni bibliografiche per camminare nella letteratura correlata se questi risultati non funzionano per le tue esigenze.

Aggiornamento: una nuova nozione di offuscamento, chiamata indistinguibile offuscamento, può mitigare il risultato di impossibilità (carta)


6

Se qualcuno vuole passare il tempo per invertire il tuo binario, non c'è assolutamente nulla che puoi fare per fermarlo. Puoi rendere se moderatamente più difficile, ma questo è tutto. Se vuoi davvero saperne di più, procurati una copia di http://www.hex-rays.com/idapro/ e disassembla alcuni file binari.

Il fatto che la CPU debba eseguire il codice è il tuo annullamento. La CPU esegue solo il codice macchina ... e i programmatori possono leggere il codice macchina.

Detto questo ... probabilmente hai un problema diverso che può essere risolto in un altro modo. Cosa stai cercando di proteggere? A seconda del problema, è possibile utilizzare la crittografia per proteggere il prodotto.


6

Per poter selezionare l'opzione giusta, dovresti pensare ai seguenti aspetti:

  1. È probabile che i "nuovi utenti" non vogliano pagare ma utilizzare il tuo software?
  2. È probabile che i clienti esistenti abbiano bisogno di più licenze di quante ne abbiano?
  3. Quanto sono disposti a pagare i potenziali utenti?
  4. Vuoi fornire licenze per utente / utenti simultanei / workstation / azienda?
  5. Il tuo software necessita di formazione / personalizzazione per essere utile?

Se la risposta alla domanda 5 è "sì", non preoccuparti delle copie illegali. Non sarebbero comunque utili.

Se la risposta alla domanda 1 è "sì", allora prima pensa ai prezzi (vedi domanda 3).

Se rispondi alle domande 2 "sì", un modello "pay per use" potrebbe essere adatto a te.

Dalla mia esperienza, pay per use + personalizzazione e formazione è la migliore protezione per il tuo software, perché:

  • I nuovi utenti sono attratti dal modello dei prezzi (scarso utilizzo -> poca retribuzione)
  • Non ci sono quasi "utenti anonimi", perché hanno bisogno di formazione e personalizzazione.
  • Nessuna restrizione software spaventa i potenziali clienti.
  • C'è un flusso continuo di denaro da parte dei clienti esistenti.
  • Ricevi feedback preziosi per lo sviluppo dai tuoi clienti, a causa di una relazione commerciale a lungo termine.

Prima di pensare di introdurre DRM o offuscamento, potresti pensare a questi punti e se sono applicabili al tuo software.


Ottimo consiglio (e l'ho votato), ma in realtà non risponde a questa particolare domanda
Mawg dice di ripristinare Monica il

5

All'inizio il codice protetto in una macchina virtuale sembrava impossibile decodificare. Themida Packer

Ma non è più così sicuro .. E non importa come impacchetti il ​​tuo codice puoi sempre fare un dump della memoria di qualsiasi eseguibile caricato e disassemblarlo con qualsiasi disassemblatore come IDA Pro.

IDA Pro viene inoltre fornito con un elegante codice assembly per il trasformatore di codice sorgente C, anche se il codice generato sarà più simile a un pasticcio matematico puntatore / indirizzo .. se lo confronti con l'originale puoi correggere tutti gli errori e strappare qualsiasi cosa.


5

Nessun dado, non puoi proteggere il tuo codice dallo smontaggio. Quello che puoi fare è configurare il server per la logica aziendale e utilizzare webservice per fornirlo alla tua app. Naturalmente, questo scenario non è sempre possibile.


8
ben detto, l'unico modo per evitare che le persone smontino il tuo codice è quello di non consentire loro di accedervi fisicamente, il che significa offrire la tua applicazione esclusivamente come SAAS, ricevere richieste dai client remoti e consegnare i dati elaborati. Posiziona il server in una stanza chiusa in un bunker sotterraneo circondato da un fossato di alligatore e un filo spinato elettrificato alto 5 m a cui butti via la chiave prima di coprire tutto con 10 m di cemento armato e poi spera di non aver dimenticato di installare tonnellate di sistemi software per prevenire intrusioni sulla rete.
jwenting

6
Spero di non avere mai il contratto per mantenere i tuoi server
Colin Pickard,

5

Per evitare il reverse engineering, non è necessario fornire il codice agli utenti. Detto questo, ti consiglio di utilizzare un'applicazione online ... tuttavia (poiché non hai fornito alcun contesto) che potrebbe essere inutile per il tuo.


questa è la vera soluzione ... vale a dire mettere i gioielli della corona nel proprio server sulla propria macchina VPS ed esporre solo le chiamate API in questo server dal client (browser o client API)
Scott Stensland

5

Probabilmente la tua migliore alternativa sta ancora usando la virtualizzazione, che introduce un altro livello di indiretta / offuscamento richiesto da bypassato, ma come ha detto SSpoke nella sua risposta , questa tecnica non è sicura al 100%.


Il punto è che non otterrai la massima protezione, perché non esiste una cosa del genere, e se mai lo sarà, non durerà a lungo, il che significa che non è stata la massima protezione in primo luogo.

Qualunque cosa l'uomo monti, può essere smontato.

Di solito è vero che il disassemblaggio (corretto) è spesso (un po 'o più) un compito più difficile, quindi il tuo avversario deve essere più abile , ma puoi presumere che ci sia sempre qualcuno di tale qualità, ed è una scommessa sicura.

Se si desidera proteggere qualcosa dalle RE, è necessario conoscere almeno le tecniche più comuni utilizzate dalle RE.

Quindi parole

Internet non è davvero pieno di risorse per la prevenzione contro il reverse engineering, ma piuttosto descrive tonnellate di informazioni su come effettuare il reverse engineering

mostra il tuo cattivo atteggiamento. Non sto dicendo che per usare o incorporare la protezione devi sapere come romperla, ma per usarla saggiamente dovresti conoscerne le debolezze e le insidie. Dovresti capirlo .

(Esistono esempi di software che utilizzano la protezione in modo errato, rendendo tale protezione praticamente inesistente. Per evitare di parlare vagamente, ti fornirò un esempio brevemente descritto in Internet: Oxford English Dictionary Second Edition su CD-ROM v4. Puoi leggere utilizzo non corretto di SecuROM nella seguente pagina: Oxford English Dictionary (OED) su CD-ROM in un ambiente Windows a 16, 32 o 64 bit: installazione su disco rigido, bug, macro di elaborazione testi, rete, caratteri e così avanti )

Tutto richiede tempo.

Se sei nuovo sull'argomento e non hai mesi o piuttosto anni per entrare correttamente nelle cose di RE, allora scegli le soluzioni disponibili fatte da altri. Il problema qui è ovvio, sono già lì, quindi sai già che non sono sicuri al 100%, ma creare la tua nuova protezione ti darebbe solo un falso senso di protezione, a meno che tu non conosca davvero lo stato dell'arte in reverse engineering e protezione (ma non è così, almeno in questo momento).

Il punto di protezione del software è spaventare i neofiti, bloccare le RE comuni e mettere un sorriso sul volto di RE esperti dopo il suo viaggio (si spera interessante) al centro della tua applicazione.

Nelle discussioni di lavoro potresti dire che si tratta di ritardare la concorrenza, per quanto è possibile.

(Dai un'occhiata alla bella presentazione Silver Needle in Skype di Philippe Biondi e Fabrice Desclaux mostrata su Black Hat 2006).


Sai che ci sono molte cose su RE là fuori, quindi inizia a leggerlo. :)

Ho detto della virtualizzazione, quindi ti darò un link a un thread esemplare di EXETOOLS FORUM : Miglior software di protezione: Themida o Enigma Protector? . Potrebbe aiutarti un po 'in ulteriori ricerche.


4

Non penso che nessun codice sia infondabile, ma i premi devono essere grandiosi perché qualcuno voglia tentarlo.

Detto questo, ci sono cose che dovresti fare come:

  • Utilizzare il massimo livello di ottimizzazione possibile (il reverse engineering non riguarda solo la sequenza di assemblaggio, ma anche la comprensione del codice e il porting in un linguaggio di livello superiore come C). Il codice altamente ottimizzato può essere un b --- h da seguire.
  • Rendi le strutture dense non avendo tipi di dati più grandi del necessario. Riorganizzare i membri della struttura tra le versioni di codice ufficiali. Anche i campi di bit riorganizzati nelle strutture sono qualcosa che puoi usare.
  • È possibile verificare la presenza di determinati valori che non devono essere modificati (un messaggio di copyright è un esempio). Se un vettore di byte contiene "vwxyz" puoi avere un altro vettore di byte contenente "abcde" e confrontare le differenze. La funzione che lo esegue non deve passare i puntatori ai vettori, ma utilizzare i puntatori esterni definiti in altri moduli come (codice pseudo-C) "char * p1 = & string1 [539];" e "char p2 = & string2 [-11731];". In questo modo non ci saranno puntatori che puntano esattamente alle due stringhe. Nel codice di confronto si confronta quindi " (p1-539 + i) - * (p2 + 11731 + i) == un certo valore". Il cracker penserà che sia sicuro cambiare stringa1 perché nessuno sembra fare riferimento a esso. Seppellisci il test in un luogo inaspettato.

Prova a hackerare tu stesso il codice assembly per vedere cosa è facile e cosa è difficile da fare. Dovrebbero sorgere idee che è possibile sperimentare per rendere il codice più difficile da decodificare e per renderlo più difficile.


2
il tuo primo punto non ha senso, il codice ottimizzato interrompe l'innesto, questo rende più facile la retromarcia (parlo per esperienza). anche il tuo punto di forza è una perdita di tempo e l'ingegnere inverso che vale la pena sale sa come eseguire il breakpoint di accesso alla memoria. questo è il motivo per cui probabilmente è meglio non progettare un sistema da soli, ma noi librerie di terze parti che devono ancora essere "violate", poiché è probabile che
durino

Dal momento che sembra che non conosca nulla sull'argomento, forse dovrei rivolgermi a un professionista come te per le mie esigenze di sviluppo del software invece di scrivere qualsiasi codice da solo.
Olof Forshell,

4

Come molti hanno già detto: su una CPU normale non puoi impedirgli di farlo, puoi semplicemente ritardarli. Come mi ha detto il mio vecchio insegnante di crittografia: non hai bisogno di una crittografia perfetta, infrangere il codice deve essere solo più costoso del guadagno. Lo stesso vale per la tua offuscamento.

Ma 3 note aggiuntive:

  1. È possibile rendere impossibile il reverse engineering, MA (e questo è molto grande ma), non è possibile farlo su una CPU convenzionale. Ho anche fatto molto sviluppo hardware e spesso sono utilizzati FPGA. Ad esempio, Virtex 5 FX dispone di una CPU PowerPC e puoi utilizzare l'APU per implementare i codici operativi della CPU nel tuo hardware. È possibile utilizzare questa funzione per decodificare realmente le istruzioni per PowerPC, che non sono accessibili dall'esterno o da altri software, o addirittura eseguire il comando nell'hardware. Poiché l'FPGA ha incorporato la crittografia AES per il suo flusso di configurazione, non è possibile decodificarlo (tranne per il fatto che qualcuno riesce a rompere AES, ma quindi credo che abbiamo altri problemi ...). In questo modo anche i fornitori di hardware IP proteggono il proprio lavoro.

  2. Parli dal protocollo. Non dite che tipo di protocollo è, ma quando è un protocollo di rete dovreste almeno proteggerlo dallo sniffing della rete. Questo puoi davvero farlo con la crittografia. Ma se vuoi proteggere l'en / decrittazione da un proprietario del software, sei tornato all'offuscamento.

  3. Rendi il tuo programma indefinibile / indefinibile. Prova a utilizzare un qualche tipo di rilevamento del debug e applicalo, ad esempio in qualche formula o aggiungendo un contenuto del registro di debug a una costante magica. È molto più difficile se il tuo programma appare in modalità debug se funziona normalmente, ma compie un calcolo, un'operazione o qualche altra cosa sbagliati. Ad esempio, conosco alcuni giochi ecologici che avevano una protezione dalla copia davvero brutta (so che non vuoi la protezione dalla copia, ma è simile): la versione rubata ha alterato le risorse estratte dopo 30 minuti di gioco e improvvisamente ne hai ottenuto solo uno risorsa. Il pirata l'aveva appena fatto crollare (vale a dire l'ingegnerizzazione inversa) - ha verificato se correva e Volia lo ha rilasciato. Tali lievi cambiamenti di comportamento sono molto difficili da rilevare, esp. se non appaiono immediatamente al rilevamento, ma solo in ritardo.

Quindi alla fine suggerirei: stimare qual è il guadagno delle persone che decodificano il tuo software, tradurlo in un po 'di tempo (ad es. Usando lo stipendio indiano più economico) e fare l'ingegneria inversa in modo da costare il tempo che è più grande.


3

Contrariamente a quanto dicono la maggior parte delle persone, in base alla loro intuizione ed esperienza personale, non penso che l'offuscamento del programma crittograficamente sicuro sia dimostrato in generale impossibile.

Questo è un esempio di una dichiarazione di programma perfettamente offuscata per dimostrare il mio punto:

printf("1677741794\n");

Non si può mai immaginare che ciò che fa realmente sia

printf("%d\n", 0xBAADF00D ^ 0xDEADBEEF);

C'è un articolo interessante su questo argomento, che dimostra alcuni risultati di impossibilità. Si chiama "Sulla possibilità (im) di programmi offuscati" .

Sebbene il documento dimostri che l'offuscamento che rende il programma non distinguibile dalla funzione che implementa è impossibile, l'offuscamento definito in qualche modo più debole potrebbe essere ancora possibile!


7
1. Il tuo esempio non è pertinente qui; i due programmi che mostri sono equivalenti dal punto di vista comportamentale e questa domanda riguarda la comprensione del comportamento di un programma, non la ricostruzione del suo codice sorgente (che, ovviamente, è impossibile). 2. Questo documento è un documento teorico; è impossibile scrivere l'offuscatore perfetto, ma è anche impossibile scrivere il decompilatore perfetto (per le stesse ragioni per cui è impossibile scrivere l'analizzatore di programmi perfetto). In pratica, è una corsa agli armamenti: chi può scrivere il migliore (de) offuscatore.
Gilles 'SO- smetti di essere malvagio' il

1
@Gilles, il risultato della (corretta) deobfuscazione sarà sempre comportamentalmente equivalente al codice offuscato. Non vedo come ciò mina l'importanza del problema.
Rotsor,

Inoltre, sulla corsa agli armamenti: non si tratta di chi investe di più nella ricerca, ma piuttosto di chi ha ragione. Le prove matematiche corrette non vanno male solo perché qualcuno vuole che lo faccia davvero male.
Rotsor,

1
Ok, forse hai ragione sulla corsa agli armamenti in pratica. Penso di aver frainteso questo. :) Spero comunque che sia possibile una sorta di offuscamento crittograficamente sicuro.
Rotsor,

Per un interessante caso di offuscamento, prova le smart card, in cui il problema è che l'attaccante ha accesso fisico (offuscamento della casella bianca). Parte della risposta è limitare l'accesso con mezzi fisici (l'attaccante non può leggere direttamente le chiavi segrete); ma anche l'offuscamento del software gioca un ruolo, principalmente per fare in modo che attacchi come DPA non diano risultati utili. Non ho un buon riferimento da offrire, scusa. Gli esempi nella mia risposta sono vagamente ispirati alle tecniche utilizzate in quel dominio.
Gilles 'SO- smetti di essere malvagio' il

3

La sicurezza attraverso l'oscurità non funziona come è stato dimostrato da persone molto più intelligenti di entrambi. Se è necessario proteggere il protocollo di comunicazione dei propri clienti, si è moralmente obbligati a utilizzare il miglior codice disponibile e completamente controllato da esperti.

Questo è per la situazione in cui le persone possono ispezionare il codice. Se la tua applicazione deve essere eseguita su un microprocessore incorporato, puoi sceglierne uno che ha una funzione di tenuta, il che rende impossibile ispezionare il codice o osservare parametri più che banali come l'uso corrente mentre è in esecuzione. (È, tranne che per le tecniche di invasione dell'hardware, che si smantella con attenzione il chip e si utilizzano apparecchiature avanzate per ispezionare le correnti sui singoli transistor.)

Sono l'autore di un assemblatore di reverse engineering per x86. Se sei pronto per una fredda sorpresa, mandami il risultato dei tuoi migliori sforzi. (Contattatemi tramite i miei siti Web.) Pochi che ho visto nelle risposte mi costituirebbero un notevole ostacolo. Se vuoi vedere come funziona il sofisticato codice di reverse engineering, dovresti davvero studiare siti Web con sfide di reverse engineering.

La tua domanda potrebbe usare alcuni chiarimenti. Come prevedete di mantenere segreto un protocollo se il codice del computer è suscettibile di reverse engineering? Se il mio protocollo fosse quello di inviare un messaggio crittografato RSA (anche la chiave pubblica), cosa guadagni mantenendo segreto il protocollo? A tutti gli effetti pratici un ispettore dovrebbe confrontarsi con una sequenza di bit casuali.

Groetjes Albert


3

Le tecniche di reverse engineering tradizionali dipendono dalla capacità di un agente intelligente che utilizza un disassemblatore di rispondere alle domande sul codice. Se desideri una forte sicurezza, devi fare cose che impediscono all'agente di ottenere tali risposte.

Puoi farlo facendo affidamento sul programma Halting ("il programma X si ferma?") Che in generale non può essere risolto. L'aggiunta di programmi di cui è difficile ragionare al programma, rende il programma difficile da ragionare. È più facile costruire tali programmi che separarli. Puoi anche aggiungere un codice al programma che presenta vari gradi di difficoltà per il ragionamento; un ottimo candidato è il programma di ragionamento sugli alias ("puntatori").

Collberg et al. Hanno un documento ("Fabbricazione di prodotti opachi poco costosi, resistenti e invisibili") che discute questi argomenti e definisce una varietà di predicati "opachi" che possono rendere molto difficile ragionare sul codice:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.1946&rep=rep1&type=pdf

Non ho visto i metodi specifici di Collberg applicati al codice di produzione, in particolare non al codice sorgente C o C ++.

L'obfuscator Java di DashO sembra usare idee simili. http://www.cs.arizona.edu/~collberg/Teaching/620/2008/Assignments/tools/DashO/


2

PRIMA COSA DA RICORDARE DI NASCONDERE IL CODICE : non tutto il codice deve essere nascosto.

LO SCOPO FINALE : Il mio obiettivo finale per la maggior parte dei programmi software è la possibilità di vendere diverse licenze che accenderanno e spegneranno funzionalità specifiche all'interno dei miei programmi.

MIGLIOR TECNICA : trovo che costruire in un sistema di hook e filtri come WordPress offre, è il metodo migliore in assoluto quando si cerca di confondere i tuoi avversari. Ciò consente di crittografare determinate associazioni di trigger senza crittografare effettivamente il codice.

Il motivo per cui lo fai è perché ti consigliamo di crittografare la minima quantità di codice possibile.

CONOSCI I TUOI CRACKER : Sappi questo: il motivo principale per decifrare il codice non è a causa della distribuzione dannosa delle licenze, è in realtà perché DEVONO cambiare il tuo codice e in realtà non DEVONO distribuire copie gratuite.

PER INIZIARE : metti da parte la piccola quantità di codice che stai per crittografare, il resto del codice dovrebbe cercare di essere stipato in UN file per aumentare la complessità e la comprensione.

PREPARARSI ALLA CRIPTA : Stai per crittografare a strati con il mio sistema, sarà anche una procedura molto complessa, quindi costruisci un altro programma che sarà responsabile del processo di crittografia.

PASSO UNO : offuscare usando i nomi base64 per tutto. Una volta fatto, base64 il codice offuscato e salvarlo in un file temporaneo che verrà successivamente utilizzato per decrittografare ed eseguire questo codice. Ha senso?

Lo ripeterò poiché lo farai ancora e ancora. Stai per creare una stringa base64 e salvarla in un altro file come variabile che verrà decrittografata e renderizzata.

PASSO DUE : leggerete questo file temporaneo come una stringa e lo offuscherete, quindi basatelo64 e lo salverete in un secondo file temporaneo che verrà usato per decrittografarlo e renderlo per l'utente finale.

PASSAGGIO TRE : Ripetere il passaggio due tutte le volte che si desidera. Una volta che hai funzionato correttamente senza errori di decrittografia, allora vorrai iniziare a costruire mine terrestri per i tuoi avversari.

LAND MINE ONE : vorrai mantenere il fatto che ti viene notificato un segreto assoluto. Quindi costruisci in un cracker un sistema di posta di avviso di sicurezza per il livello 2. Questo verrà lanciato per farti conoscere le specifiche del tuo avversario se qualcosa dovesse andare storto.

LAND MINE TWO : Dipendenze. Non vuoi che il tuo avversario sia in grado di eseguire il livello uno, senza il livello 3 o 4 o 5, o anche il programma reale per cui è stato progettato. Quindi assicurati che all'interno del livello uno includa una sorta di kill script che si attiverà se il programma non è presente, o gli altri livelli.

Sono sicuro che puoi inventare le tue mine antiuomo, divertirti.

COSA RICORDARE : puoi effettivamente crittografare il tuo codice invece di base64. In questo modo un semplice base64 non decodificherà il programma.

PREMI : tieni presente che questa può effettivamente essere una relazione simbiotica tra te e il tuo avversario. Metto sempre un commento all'interno del primo livello, il commento si congratula con il cracker e dà loro un codice promozionale da utilizzare per ricevere un premio in denaro da te.

Rendi significativo il premio in denaro senza pregiudizi. Normalmente dico qualcosa come $ 500. Se il tuo ragazzo è il primo a decifrare il codice, allora pagagli i suoi soldi e diventa suo amico. Se è un tuo amico non distribuirà il tuo software. Chiedigli come ha fatto e come puoi migliorare!

IN BOCCA AL LUPO!


4
Hai persino letto la domanda? Non ho mai chiesto metodi su come proteggere dalla pirateria. L'applicazione sarà gratuita, è il protocollo sottostante utilizzato che deve essere protetto a causa della natura della sicurezza.
graphitemaster,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.