Jump to content
co4ie

Nytro @ DefCamp Prezentare

Recommended Posts

Posted

@Nytro: interesanta prezentarea dar sunt curios de o chestie, atunci cand faci patch-ul API-ului(presupun ca e un far jump de 5 octeti) cum te asiguri ca pici exact intre instructiuni? majoritatea probabil incep cu "push ebp; mov ebp, esp"=5 octeti, dar exista posibilitatea sa inceapa cu altceva si sa spargi o instructiune.

Posted (edited)

Cum se face "safe":

Microsoft WinAPI au acel "mov edi, edi" - 2 bytes care nu fac nimic si un singur ciclu de procesor special pentru asa ceva. Chiar daca era doar "push ebp, mov ebp, esp" tot nu era thread safe deoarece poate se executa prima instructine, apoi se punea hook si crapa. Doar WinAPI cu acel mov edi, edi permit sa fie sigur, se pune un jmp -5 (2 bytes, short jump, in loc de acel "mov edi, edi") si inainte de fiecare winapi sunt 5 NOP-uri in care se pune lejer un jmp.

Util: Why do Windows functions all begin with a pointless MOV EDI, EDI instruction? - The Old New Thing - Site Home - MSDN Blogs

A, am inteles intrebarea:

0. Cand pun hook-ul pastrez primii 5 bytes ai functiei intr-o variabila globala

1. Pun jmp indiferent de ce instructiune este si schimb astfel primii 5 bytes

2. In codul meu, la care se sare cu acel jump, fac "restore" la bytes originali

3. Schimb "return EIP-ul" de pe stack (ESP in momentul apelului)

4. Apelez functia originala si fac diverse lucruri normale

5. Return EIP-ul e modificat sa cada intr-o alta functie de-a mea, "reinsert_hook"

6. Acolo pun din nou hook-ul si ciclul continua

Edited by Nytro
Posted

Uitasem de mov edi,edi. push ebp, mov ebp, esp sunt doar 3 octeti.

Interesanta chestia cu un patch pe alea 5 NOP-uri si un jmp in spate nu stiam ca e facuta intentionat si ca cel putin la dll-urile din Windows poti sa te bazezi pe ea.

Daca faci restore la cei 5 octeti la fiecare apelare atunci metoda nu pare a fi thread safe.

Eu fac altfel ca sa nu trebuiasca sa mut mereu instructiunile sau sa ma joc direct cu stack-ul:

1. iau primii 5* octeti din API de la adresa XXXX si ii pun la adresa YYYY. In locul lor pun un jump catre functia mea de hook(cum faci si tu la 0. si 1.)

2. dupa cei 5 octeti, la YYYY+5, pun un jump catre restul API-ului la adresa XXXX+5

3. cand se apeleaza API-ul face jump catre functia mea care isi face treaba cu parametrii apoi apeleaza YYYY ca pe API-ul initial.

4. cand apeleaza YYYY se executa primii 5 octeti apoi se sare la restul API-ului la XXXX+5.

5. pentru ca YYYY e apelata de catre functia de hook atunci returneaza tot in functia de hook asa ca apelantului initial pot sa-i returnez orice valoare.

Problema ambelor metode este ca la unele API-uri si la DLL-uri de la alti vendori o functie nu incepe intotdeauna cu cele trei instructiuni de 5 octeti, adica poate fi una de 2 apoi una de 4 sau de 5 sau orice alta combinatie insumand mai mult de 5 creand probleme cand iei fix 5 octeti pentru ca spargi o instructiune in doua si nu o sa se execute corect. Asta intrebam de fapt, daca ai gasit o alta solutie sa tratezi situatiile astea.

Solutia mea e un mic dissassembler care imi da dimensiunea instructiunilor ca sa nu le sparg deci 5* de mai sus poate varia intre 1 si 15.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...