Domanda:
Come si può decomprimere manualmente un driver Windows in modo affidabile?
Ange
2013-03-30 01:43:20 UTC
view on stackexchange narkive permalink

Quando si decomprime manualmente un eseguibile in modalità utente di Windows, è possibile interrompere facilmente il suo EntryPoint (o TLS), quindi tracciare fino a raggiungere l'EntryPoint originale. Tuttavia questo non è possibile con un driver compresso.

Come puoi decomprimere manualmente un driver Windows in modo affidabile?

A chi non manca il più grande di tutti, Softice
Quattro risposte:
#1
+16
mrduclaw
2013-03-30 07:19:14 UTC
view on stackexchange narkive permalink

Mi piace la tua risposta sulla modifica del sottosistema, specialmente se non sei un fan del debug del kernel. Sono un grande fan di Windbg, però. Il modo in cui lo faccio è:

  1. Collega il mio debugger del kernel a una VM
  2. Cambia il primo byte del punto di ingresso del driver in INT3 (0xCC).
  3. Correggi il checksum PE (sono un fan di lasciare che pefile faccia questo lavoro per me).
  4. Carica il driver nella VM ( OSR ha un ottimo caricatore di driver)

Il kernel dovrebbe chiamare DriverEntry () sul tuo driver ed entrare nel tuo debugger per te. Quindi puoi tracciare il codice fino a trovare l'OEP come avresti fatto comunque. Il vantaggio principale che vedo in questo metodo è che non devi falsificare le DLL del kernel o le chiamate che il driver potrebbe eseguire durante lo spacchettamento e funziona su x64.

Tuttavia, potresti colpire il muro con le versioni più recenti di Windows. La risposta dell'OP è più versatile in questo senso, ma la tua è sicuramente più professionale :) ... inoltre non dimenticare `devcon` per le esigenze di caricamento dei driver (viene fornito con il sorgente nei DDK / WDK)
@0xC0000022L Non ho avuto problemi con questo sulle versioni più recenti di Windows; basta fare le cose normali come abilitare la firma di prova, ecc. Certo, non l'ho provato su Windows 8, però. È cambiato qualcosa?
@mrduclaw come faccio a modificare il primo byte del punto di ingresso del driver in un INT3?! ??
@AminM Ci scusiamo per la risposta tardiva, non ho controllato questo account da molto tempo. Apri il file in IDA, trova i byte di dove si trova il punto di ingresso. Aprilo in un editor esadecimale e modificalo in 0xCC (break-point). Oppure puoi probabilmente modificarlo direttamente in IDA in questi giorni. In bocca al lupo!
#2
+11
Ange
2013-03-30 01:43:20 UTC
view on stackexchange narkive permalink
  1. cambia il sottosistema del driver in GUI (trasformandolo in un binario in modalità utente)
  2. cancella l'RVA delle importazioni o usa un set di false DLL del kernel (solo a 32 bit) per abilitare il caricamento delle importazioni
  3. avvia nel tuo debugger e procedi come se fosse in modalità utente: probabilmente dovrai simulare alcune chiamate API prima di raggiungere l'EntryPoint originale.
#3
+8
ekse
2013-08-14 01:15:14 UTC
view on stackexchange narkive permalink

Un'alternativa alla patch della funzione DriverInit con un INT3 consiste nell'inserire un punto di interruzione nella funzione IopLoadDriver che è responsabile della chiamata di DriverInit. In Windows XP SP3, il punto di interruzione deve essere aggiunto a IopLoadDriver + 0x66a che è call dword ptr [edi + 2Ch] (0x2C è _DRIVER_OBJECT.DriverInit).

  1. Trova IopLoadDriver con x nt! IopLoadDriver
  2. Aggiungi un punto di interruzione in IopLoadDriver + 0x66a
  3. Carica e avvia il tuo driver

Offset per altre versioni di Windows:

  • Windows 7 Pro SP1 32 bit Tedesco: nt! IopLoadDriver + 0x7eb
  • Windows 7 Ultimate 64 bit US: nt! IopLoadDriver + 0xA04
  • Windows 10 Pro x64 US: nt! IopLoadDriver + 0x51C (Build 10586.420)

(Se hai offset per altre versioni di Windows , modifica questa risposta)

Un bel po 'di informazioni. È sempre prezioso avere pezzi e pezzi che puoi mettere insieme come invertitore. Ricorda inoltre che puoi ottenere una buona idea dei dettagli di implementazione in Windows guardando il codice sorgente di ReactOS.
#4
+6
blabb
2013-08-14 05:43:33 UTC
view on stackexchange narkive permalink

nt! IopLoadDriver chiamata indiretta viene utilizzata solo per la voce di avvio del driver di SERVICE_DEMAND

per l'avvio dei driver che dovresti interrompere su nt! IopInitializeBuiltInDriver anche una chiamata indiretta

puoi vedere un breve esempio sul messaggio # 17 & # 18 in questo link

http://www.osronline.com/showthread.cfm ? link = 231280

questoèuno script dormiente (leggermente modificato per usare gc (vai da condizionale invece di andare come consigliato) che continua ad aspettare per sempre e stamperà i dettagli! drvobj quando mai driver viene caricato in una sessione di debug del kernel

nessuna parola racchiude il comando dovrebbe essere su una singola riga

  .foreach / pS 1 / ps 10 (place {# call * dword * ptr * \ [* \ + * \] nt! IopInitializeBuiltinDriver}) {bu place ".printf \"% msu \\ n \ ", poi (esp + 4); r $ t0 = poi (esp); gu ;! drvobj $ t0 2; gc "}. foreach / pS 1 / ps 10 (place {# call * dword * ptr * \ [* \ + * \] nt! IoploadDriver}) {bu place" .printf \ "% msu \\ n \ ", poi (esp + 4); r $ t1 = poi (esp); gu;! drv obj $ t1 2; gc "}  

xp sp3 vm

in una sessione kd connessa do sxe ibp; .reboot kd richiederà un'interruzione iniziale al riavvio (equivalente a / break switch in boot.ini) quando non funziona esegue questo script

  $$ >a< "thisscript.extension"  codice> 

oltre a stampare tutti i punti di ingresso del driver di sistema e i relativi oggetti driver

se la tua applicazione carica un driver aggiuntivo verranno stampati anche i loro dettagli

un output di esempio per dbgview di sysinternals aperto nella vm di destinazione

il punto di ingresso dbgv.sys viene chiamato quando contrassegna l'abilitazione dell'acquisizione del kernel (ctrl + k)

  \ REGISTRY \ MACHINE \ SYSTEM \ ControlSet001 \ Services \ DBGV *** ERRORE: caricamento del modulo completato ma impossibile caricare i simboli per l'oggetto Dbgv.sysDriver (ffbd6248) è per: \ Driver \ DBGVDriverEntry: f6d89185 DbgvDriverStartIo : 00000000 DriverUnload: 00000000 AddDevice: 00000000 Routine di spedizione:
[00] IRP_MJ_CREATE f6d87168 Dbgv + 0x1168 [01] IRP_MJ_CREATE_NAMED_PIPE 804fa87e points! IopInvalidDeviceRequest [02] IRP_MJ_CLOSE f6d87168 Dbgv + 0x1168 [03] IRP_MJ_READ 804fa87e punti! IopInvalidDeviceRequest [04] IRP_MJ_WRITE 804fa87e points! IopInvalidDeviceRequest [05] IRP_MJ_QUERY_INFORMATION 804fa87e punti! IopInvalidDeviceRequest 06 IRP_MJ_SET_INFORMATION 804fa87e points! IopInvalidDeviceRequest [07] IRP_MJ_QUERY_EA 804fa87e points! IopInvalidDeviceRequest [08] IRP_MJ_SET_EA 804fa87e points! IopInvalidDeviceRequest [09] IRP_MJ_FLUSH_BUFFERS 804fa87e points! IopInvalidDeviceRequest [0a] IRP_MJ_QUERY_VOLUME_INFORMATION 804fa87e punti! IopInvalidDeviceRequest [0b] IRP_MJ_SET_VOLUME_INFORMATION 804fa87e punti! IopInvalidDeviceRequest IRP_MJ_DIRECTORY_CONTROL [0c] 804fa87e nt! IopInvalidDeviceRequest [0d] IRP_MJ_FILE _SYSTEM_CONTROL 804fa87e punti! IopInvalidDeviceRequest [0e] IRP_MJ_DEVICE_CONTROL f6d87168 Dbgv + 0x1168 [0f] IRP_MJ_INTERNAL_DEVICE_CONTROL 804fa87e points! IopInvalidDeviceRequest [10] IRP_MJ_SHUTDOWN 804fa87e 11 punti! IopInvalidDeviceRequest IRP_MJ_LOCK_CONTROL 804fa87e 12 punti! IopInvalidDeviceRequest IRP_MJ_CLEANUP 804fa87e punti! IopInvalidDeviceRequest [13] 804fa87e IRP_MJ_CREATE_MAILSLOT 14 punti! IopInvalidDeviceRequest IRP_MJ_QUERY_SECURITY 804fa87e 15 points! IopInvalidDeviceRequest IRP_MJ_SET_SECURITY 804fa87e 16 points! IopInvalidDeviceRequest IRP_MJ_POWER 804fa87e 17 punti! IopInvalidDeviceRequest IRP_MJ_SYSTEM_CONTROL 804fa87e 18 points! IopInvalidDeviceRequest IRP_MJ_DEVICE_CHANGE 804fa87e 19 punti! IopInvalidDeviceRequest IRP_MJ_QUERY_QUOTA 804fa87e punti! IopInvalidDeviceRequest
[1a] IRP_MJ_SET_QUOTA 804fa87e nt! IopInvalidDeviceRequest [1b] IRP_MJ_PNP 804fa87e nt! IopInvalidDeviceRequest  


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...