Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature may not be available in some browsers.
Per progettare una vera virtualizzazione devi trasformare le istruzioni x86 in bytecode, il codice verrà eseguito più lentamente e spesso non è semplice da ottimizzare. Il lavoro deve essere affettato nei minimi particolari: vuoi meccanizzare una procedura di virtualizzazione presumibilmente per intricare il reversing di un programma, quindi applicherai certe espedienti come l'anti-debug (e altre, tra cui alcune simili) di Themida (non saprei di VMProtect). Te lo consiglio perchè da quello che ho capito non vuoi fare un lavoro tanto consistente come quello di questi packer, ma se ne viene fuori qualcosa di scadente e mi lasci analizzare così facilmente l'intero set di istruzioni che il packer utilizza non ci vuole tanto a bypassare la virtualizzazione, un buon reverser vince a mani basse. A livello pratico, tradizionalmente avendo un programma packato (da packer come questi) unpacki la virtualizzazione a occhio e croce così:Quindi ho deciso di cimentarmi in un impresa non da poco, ho gia' creato qualche packer nativo, che seppur semplice ha qualche trick interessante, ora voglio sviluppare una protezione di tipo VM simile a quelle di Themida o VMProtect, non voglio realizzare un software professionale che richiederebbe un team intero, mi basta realizzarlo solo per software a 32 bit e con istruzioni asm comuni.
Leggi bene:Mi spiego meglio, in quel pdf fa proprio l'esempio dell'handler NOR
"NOR" è il "logical gate", l'istruzione, o meglio una inferriata logica di quell'handler. Dovrebbe chiarirti un po' le idee."In fact all those operations are managed by one handler "NOR" logical gate"
Questi tipi di handler servono per formare l'astrazione del codice non virtualizzato, non sono random. C'è una logica dietro.Anche essendo gli opcode della vm random
VMProtect sembra non supportare la virtualizzazione di istruzioni tipo SIMD (non e' possibile capire immediatamente che si riferisce a quell'handler? Oppure hanno una sorta di mutation come quella su cui hai fatto la guida del codice metamorfo?
AND
, SUB
, OR
), e quell'handler attraverso l'istruzione nor
(che non esiste in x86, e va tradotto successivamente in codice assembly in base ai costrutti per come è stata elaborata) fa capire come vengono eseguite. nor
accetta 2 parametri, esempio: and ecx,eax
è rappresentata come NOR(NOR(ecx, ecx) NOR(eax,eax))
.Figurati. ^^
Non volevo entrare nel merito del caso di specie per non fuorviarti magari, ma aggiungo una cosa.
Io ho una lib per la decodifica delle istruzioni, l'ho scritta per integrarla in un progetto "giocattolo".
Non saprei se può esserti utile per com'è impostata: dato un file offset (ma con un VA si comporterebbe allo stesso modo) decodifica le istruzioni nelle varie parti che la compongono (prefissi, opcode, imm, disp, sib byte,...) e tiene traccia della lunghezza (così da decodificare l'istruzione successiva). Architetture target x86 e x86_64.
Questo solo per la decodifica delle istruzioni (nel senso che non ha una logica all'interno).
Dovrei apportare qualche cambiamento (pulizia al codice in particolare), ma quando la renderò pubblica (ahimè non in tempi brevissimi temo), te la linko (magari può servirti anche solo per darti idee/spunti).
NOT QWORD_OP_1
NOT QWORD_OP_2
AND QWORD_OP_1, QWORD_OP_2
MOV QWORD_OP_2, QWORD_OP_1
MOV QWORD_OP_1, RFLAGS
Grazie per i chiarimenti"NOR" è il "logical gate", l'istruzione, o meglio una inferriata logica di quell'handler. Dovrebbe chiarirti un po' le idee.
Questi tipi di handler servono per formare l'astrazione del codice non virtualizzato, non sono random. C'è una logica dietro.
VMProtect sembra non supportare la virtualizzazione di istruzioni tipo SIMD (AND
,SUB
,OR
), e quell'handler attraverso l'istruzionenor
(che non esiste in x86, e va tradotto successivamente in codice assembly in base ai costrutti per come è stata elaborata) fa capire come vengono eseguite.nor
accetta 2 parametri, esempio:and ecx,eax
è rappresentata comeNOR(NOR(ecx, ecx) NOR(eax,eax))
.
E no, non stiamo parlando di metamorfismo. Devi comunque studiare il codice prima.
Ribadisco: non c'è niente di random con quelle istruzioni, c'è una logica dietro. Themida però offre la generazione dinamica degli opcode nella VM, se intendi qualcosa del genere.Si intendevo dire che l'opcode e' random, non l'handler, nel senso che il valore dell'opcode di AND cambia da vm a vm ma poi andra' comunque ad usare NOR in quella modalita'
Ciò che realmente vuoi è devirtualizzare il programma con la scaletta che ho descritto sopra. Poi l'analisi statica è un conto, il debugging ne è un altro (è parte dell'analisi dinamica).quindi la mia domanda era: la loro implementazione di NOR puo' essere identificata immediatamente da un analisi statica anche su diversi eseguibili e da questo debuggando risalire a gli opcode che la usano? (NOR per fare un esempio, visto che era citato nel pdf, ma mi riferisco anche a gli altri handler, che magari avendo piu' istruzioni lasciano una signature piu' evidente)
Step chiari e concisi, infatti la parte che piu' mi preoccupa e' tradurre l'assembly originale nei miei opcodes, soprattutto per quanto riguarda i jump, dentro la VM, fuori ed alle API di windows (mi piacerebbe fare un handler apposito che non usa la IAT ed evita hook su LoadLibrary/GetProcAddress), grazie anche per il link.In questi casi la prima cosa da fare è capire esattamente come funziona la VM in questi packer che hai menzionato.
Ovviamente non è facile perchè questi sono complessi.
Ma in generale, quello che devi fare è "inventarti" una tua architettura, e crearne un contesto completo (ad esempio decidere numero di registri ed allocarli, una lista di opcodes che consentano di eseguire quante più operazioni possibile, creare il vm stack ecc.).
A questo punto devi analizzare l'assembly originale e tradurlo in opcodes adatti alla tua macchina (questa è l'operazione più lunga e complessa).
Ora non ti resta che creare la macchina stessa, ovvero creare un parser dei tuoi opcodes, ognuno dei quali farà riferimento ad uno specifico handler.
Ci sono stati vari tutorials riguardo a questa parte ma personalmente non ne ho mai visti di completi e semplici da capire.
uno abbastanza semplice è qui: https://resources.infosecinstitute....ering-simple-virtual-machine-protection/#gref
Ribadisco: non c'è niente di random con quelle istruzioni, c'è una logica dietro. Themida però offre la generazione dinamica degli opcode nella VM, se intendi qualcosa del genere.
Ciò che realmente vuoi è devirtualizzare il programma con la scaletta che ho descritto sopra. Poi l'analisi statica è un conto, il debugging ne è un altro (è parte dell'analisi dinamica).
[...]
The opcode choices are motivated by the equivalent x86 opcode organization and by the sake of simplifying the manipulation of instructions and the coding of transformations. In particular, for the first type of opcodes, the opcode itself (for instance ADD) is encoded into bits 6..3, and the operand types into bits 2..0 and 7: bit 7 specifies whether the operands are 8 bits (for instance mov al, 12h) or 32 bits (for instance mov eax, 12h) whereas bits 2..0 specify the type of operands (Reg, Imm, etc.).
Finally, a pseudo-instruction is encoded in 16 bytes:
Codice:XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX OP *--------- operands --------* LM *- instr -*
OP contains the instruction opcode, on one byte. Then the operands are encoded (register index, memory address or immediate value) on the following 10 bytes. Then LM (“Label Mark”) is a flag on 1 byte telling whether this instruction is the target of a branching instruction: when this is the case, the instruction can neither be deleted nor compressed with instructions preceding it. The last 4 bytes contain a pointer which has miscellaneous significations along the execution: during the disassembly, it contains the address of the initial x86 instruction, during the permutation, it contains the instruction’s address inside the non-permutated code, etc.
A proposito dell'aspetto che ti preoccupa di più, ti ho allegato un PDF.
Tra le altre cose parla di MetaPHOR (sezione C); è vecchio ormai, tuttavia utilizzava uno pseudo instruction-set per rappresentare le istruzioni (x86). Estrapolo una piccola sezione (p. 8):
Penso possa darti qualche idea su come e cosa fare (e cosa no).
@EvOlUtIoN_OGM come stai? Sono felice di vederti ancora da queste parti!