2012-03-07 10 views
5

Sto tentando di iniettare una DLL a 64 bit in un processo a 64 bit (esploratore per la questione).
Ho provato a utilizzare le tecniche di Threading remoto \ Window, ma alcuni Anti-virus rilevano il mio caricatore come un falso positivo.
Dopo aver letto questo articolo: Dll Injection by Darawk, ho deciso di utilizzare le caverne di codice.
Ha funzionato alla grande per 32 bit ma poiché VS non supporta l'assembly inline per 64 bit, ho dovuto scrivere esplicitamente i codici op e gli operandi.
Ho guardato questo articolo: 64Bit injection using code cave, come afferma l'articolo, ci sono alcune differenze:Iniezione di DLL a 64 bit utilizzando la caverna del codice

Ci sono molte differenze che dovevano essere incorporati qui:

  1. MASM64 utilizza fastcall, quindi la funzione di l'argomento deve essere passato in un registro e non nello stack.
  2. La lunghezza degli indirizzi - 32 vs 64 bit - deve essere presa in considerazione.
  3. MASM64 non ha istruzioni che lo spinga tutti i registri nello stack (come pushad in 32 bit), quindi questo ha dovuto eseguire premendo tutti i registri in modo esplicito.

ho seguito tali orientamenti e corse l'esempio del articolo, ma niente di tutto quello che ho fatto lavorato.
Il processo di destinazione si è interrotto nel momento in cui ho ripreso il thread principale e non so come guardarlo veramente perché ollydbg non ha supporto a 64 bit.

Questo è come il codice sia prima che io iniettato:

codeToInject: 
000000013FACD000 push  7741933Ah 
000000013FACD005 pushfq 
000000013FACD006 push  rax 
000000013FACD007 push  rcx 
000000013FACD008 push  rdx 
000000013FACD009 push  rbx 
000000013FACD00A push  rbp 
000000013FACD00B push  rsi 
000000013FACD00C push  rdi 
000000013FACD00D push  r8 
000000013FACD00F push  r9 
000000013FACD011 push  r10 
000000013FACD013 push  r11 
000000013FACD015 push  r12 
000000013FACD017 push  r13 
000000013FACD019 push  r14 
000000013FACD01B push  r15 
000000013FACD01D mov   rcx,2CA0000h 
000000013FACD027 mov   rax,76E36F80h 
000000013FACD031 call  rax 
000000013FACD033 pop   r15 
000000013FACD035 pop   r14 
000000013FACD037 pop   r13 
000000013FACD039 pop   r12 
000000013FACD03B pop   r11 
000000013FACD03D pop   r10 
000000013FACD03F pop   r9 
000000013FACD041 pop   r8 
000000013FACD043 pop   rdi 
000000013FACD044 pop   rsi 
000000013FACD045 pop   rbp 
000000013FACD046 pop   rbx 
000000013FACD047 pop   rdx 
000000013FACD048 pop   rcx 
000000013FACD049 pop   rax 
000000013FACD04A popfq 
000000013FACD04B ret 

sembra che vada bene per me, ma immagino che mi manca qualcosa.
Il mio codice completo può essere trovato qui: Source code

Qualche idea \ suggerimenti \ alternative?

+1

Cosa c'è di sbagliato nell'usare WinDbg per il debug? Supporta perfettamente i processi nativi x64, e trovo che sia molto più stabile e affidabile di OllyDbg. – RaptorFactor

+0

Stai effettuando l'iniezione da un processo a 64 bit? In caso contrario, non è possibile utilizzare l'indirizzo di "LoadLibrary". – pezcode

+2

Inoltre, assicurarsi che lo stack sia allineato a 16 byte dopo aver chiamato 'LoadLibrary'. – pezcode

risposta

1

Apparentemente, il problema principale era che ho assegnato i dati della caverna del codice senza l'autorizzazione EXECUTE_PAGE_READWRITE e quindi il blocco dei dati è stato considerato come dati e non come opcode.

+0

Omer, qual era la correzione esatta? Ho provato a riutilizzare il codice aggiungendo il flag PAGE_EXECUTE_READWRITE per l'allocazione della code cave sulla riga 97, ma il blocco persisteva per me. Puoi condividere il tuo codice finale? – zah

+2

Non importa, risolvilo applicando tutti i suggerimenti pezcode: http://pastebin.com/34xCSrL2 – zah

3

Il primo push che memorizza il valore di ritorno spinge solo un valore a 32 bit. dwOldIP nel tuo codice è un DWORD, dovrebbe essere un DWORD64. Avere il cast a ctx.Rip dovrebbe essere stato abbastanza di un suggerimento;)

Inoltre, assicurarsi che lo stack sia allineato a 16 byte quando si è entrati nella chiamata a LoadLibrary. Alcune API generano eccezioni se lo stack non è allineato correttamente.

+0

Mezzi di allineamento dello stack, RSP deve essere un multiplo di 16. È responsabilità dell'utente garantire che, ad es. impostando un corretto stack frame. – pezcode

+0

Mi è sembrato strano il motivo per cui l'autore ha scelto di scattare solo il DWORD inferiore dell'IP, ho provato a risolverlo, sono molto arrugginito @ ASM quindi non sono sicuro di quello che ho fatto è giusto. Non c'è modo di spingere direttamente un numero a 64 bit così ho spinto 2 X segnaposto DWORD e copiato l'intero registro RIP ma si blocca ancora, ho anche guardato se c'è una specie di codice di allineamento dello stack prima della chiamata e non ce n'è. altri pensieri? Grazie – Omer

+0

Puoi anche usare 'mov rax, old_eip; spingere rax', forse in qualche modo non stai copiando correttamente le due parti. Onestamente, per favore, fai il debug del tuo codice. Possiamo continuare a indovinare qual è il tuo problema o potresti semplicemente vedere dove si blocca. – pezcode