2015-05-11 16 views
5

Sto lavorando a un convertitore binario non nativo di runtime in Windows e finora sono riuscito a "intercettare" gli interrupt (ad es. INT 0x99) per i binari del sistema operativo che sto cercando di emulare utilizzando un brutto attacco che utilizza Windows SEH per gestire interruzioni non valide; ma solo perché il vettore chiamata di sistema è diverso da quello di Windows, che mi permette di catturare queste eccezioni "soft" facendo qualcosa di simile a questo:"Trapping" delle chiamate sysenter di un processo nello spazio utente su Windows

static int __stdcall handler_cb(EXCEPTION_POINTERS* pes, ...) 
{ 

    if (pes->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) 
     return EXCEPTION_CONTINUE_SEARCH; 

    char* instruct = (char*) pes->ContextRecord->Eip; 

    if (!instruct) 
     handle_invalid_instruction(instruct); 

    switch (instruct[0]) 
    { 
     case 0xcd: // INT 
     { 
      if (instruct[1] != 0x99) // INT 0x99 
       handle_invalid_instruction(instruct); 
      handle_syscall_translation(); 
      ... 
     } 
     ... 
     default: 
      halt_and_catch_fire(); 
    } 
    return EXCEPTION_SUCCESS; 
} 

che funziona abbastanza bene (ma lentamente), il problema con questo è che Windows tenta prima di gestire l'istruzione/interrupt, e per i binari non nativi che usano sysenter/sysexit invece di int 0x99, alcune istruzioni systenter nel binario non nativo sono effettivamente chiamate al kernel NT valide quando eseguite, ovvero il mio gestore non viene mai chiamato, e peggio; anche lo stato del sistema operativo "host" è compromesso. C'è un modo per "intrappolare" le istruzioni di sysenter in Windows? Come potrei fare questo?

+1

È in esecuzione in modalità a 64 bit o in modalità a 32 bit (WOW64)? –

+0

È in modalità di comparabilità a 32 bit poiché i file binari che sto emulando sono 32 bit – joshumax

+0

Suppongo che non sia importante, perché SYSENTER è comunque valido su 32 bit. Non sono sicuro che le versioni di Windows a 32 bit supportino SYSENTER, ma a quanto pare (dalla tua sperimentazione), lo fanno. –

risposta

2

Per quanto ne so, non c'è modo (da un processo in modalità utente) di "disabilitare" SYSENTER, in modo che l'esecuzione genererà un'eccezione. (Suppongo che i tuoi programmi non provino a SYSEXIT, perché solo Ring 0 può farlo).

L'unica opzione che penso che hai è fare come VirtualBox fa, e la scansione per le istruzioni non valide, la loro sostituzione con codici operativi illegali o qualcosa di simile, che si può trappola, ed emulare. Vedi 10.4. Details about software virtualization.

Per risolvere questi problemi di prestazioni e sicurezza, VirtualBox contiene un codice di scansione e Analysis Manager (CSAM), che smonta il codice ospite, e il Patch Manager (PATM), che può sostituirlo in fase di esecuzione.

Prima di eseguire il codice dello squillo 0, CSAM lo esamina in modo ricorsivo per rilevare le istruzioni problematiche. PATM esegue quindi il patching in-situ, cioè sostituisce l'istruzione con un salto alla memoria dell'hypervisor in cui un generatore di codice integrato ha posizionato un'implementazione più idonea. In realtà, questo è un compito molto complesso in quanto vi sono molte situazioni strane da scoprire e gestire correttamente. Quindi, con la sua attuale complessità, si potrebbe sostenere che PATM è un recompiler in-situ avanzato.