Küsimus:
Konksu lõpp / funktsiooni keskosa
Sean Heiss
2013-07-14 04:43:23 UTC
view on stackexchange narkive permalink

Kuidas saaksin kuskile haakuda, välja arvatud funktsiooni algus? Püüan lisada funktsioone kolmanda osapoole käivitatavale failile ja mul on seda vaja koodi täielikuks täitmiseks ja seejärel selle andmete edastamiseks minu funktsioonile. Ma ei kujuta ette, kuidas seda teha.

Kas selleks on lihtne viis? Ma ei leia ühtegi haakivat mootorit, mis seda rakendaks. Ma ei leia selle kohta kuskilt mingit teavet.

Nägin kedagi ütlemas, et võite lisada ebaseadusliku opkoodi ja seejärel püüda erandi, kuid ma ei tea, kuidas seda teha.

Näide (pseudokood):

  int moveCharacter (int x, int y) {x + = 5; y + = 5; tagastage 0;}  

Oletame, et tahan haakida otse enne return 0 ja andke uued x ja y muutujad minu enda funktsioonile (sisestatud DLL-is või koodikoobas), mis kirjutab muutujad logifaili. Pärast oma funktsiooni soovin naasta algse funktsiooni juurde, et see saaks tavapäraselt naasta.

Kolm vastused:
peter ferrie
2013-07-14 09:05:30 UTC
view on stackexchange narkive permalink

Põhjus, miks funktsiooni lõppu haakimiseks pole mootoreid, on see, et on raske kindlaks teha, kus see asub või kas see üldse olemas on. Funktsioonil on üks sisestuspunkt, kuid sellel võib olla mitu väljumispunkti, sealhulgas pole ühtegi (arvestage väljumisega ()). Väljumiskohal võib olla ka mitut tüüpi - return, viskamine (), longjmp (), C ++ EH jne.

Üldine mõte pärast funktsiooni lõpuleviimist on helistaja ümbersõitmine, kuid vajaliku jaoks on juba liiga hilja. Igatahes tehakse seda nii: kõigepealt eemaldage huvipakkuv funktsioon, mis haakib täitmise alguse. Kui saate juhtimise, ühendage funktsioon lahti ja lugege virnast tagasi aadressi (eeldades, et funktsioon reaalselt naaseb). Seejärel ümbersõit pöördusaadress (helistaja) ja laske siis algsel funktsioonil käivitada. Kui saate uuesti juhtimise, on funktsioon oma täitmise lõpetanud. Saate tagastusaadressi lahti haakida, teha täiendavaid toiminguid ja seejärel jätkata täitmist. Kahjuks kaotate juurdepääsu kohalikele muutujatele (mida teie kirjelduse põhjal näite soovivat). Selle probleemi vältimiseks on üks viis funktsioon läbi, installides üheastmelise erandi saamiseks Vectored Exception Handler. See võimaldaks teil uurida käsku, mis järgmisena täidetakse (kuna erand toimub pärast eelmise käsu täitmist) ja kui see on tagastuskäsk, saate väärtused logida.

erandmeetod, installiksite oma koodile osutamiseks Vectored Exception Handler'i ja asetaksite seejärel huvipunkti murdepunkti juhise. Jällegi on probleem kindlaks teha, kus see koht asub.

Jason Geffner
2013-07-14 05:34:27 UTC
view on stackexchange narkive permalink

Microsofti ümbersõidud muudab selle väga lihtsaks. Kirjutaksite tegelikult järgmise koodi (turvalisuse huvides soovite teha ka muid kõnesid, näiteks DetourUpdateThread () ):

  DetourTransactionBegin () ; DetourAttach (& (PVOID&) OriginalFunction, Function); DetourTransactionCommit ();  

Ja siis pidage oma konksuks järgmist koodi:

  int Funktsioon (int x) {int r = OriginalFunction (x); // Siit käsitsege r, tagastades r;}  
Mulle jäi mulje, et ümbersõite saab kasutada ainult enne teist funktsiooni. Selle asemel, et muuta funktsiooni algseks funktsiooniks OriginalFunction, võiksin sellest teha midagi? Lisasin oma põhipostitusele näite, et proovida selgitada, mida ma teha tahan.
Ah, teil on vaja juurdepääsu kohalikele virna muutujatele. Sellisel juhul lappige oma konksu funktsioonile lihtsalt sihtfunktsiooni ret-käsk jmp-ga.
Ümbersõitudel on siiski üsna piirav EULA. Ei sobi paljudel eesmärkidel.
David Hoelzer
2013-07-14 06:07:28 UTC
view on stackexchange narkive permalink

Palju lihtsam lähenemine on tuvastada punkt, kus kood on tegelikult teie jaoks vajalikud andmed genereerinud. Kui leiate selle asukoha, asendage järgmised mitu baiti kõne või kaugkõnega oma koodile. Pange hoolikalt tähele baidid, mille üle kirjutate. (Kõrvalepõikena soovitan pigem helistada kui kaugkõne, mitte jmp-i, et ma ei peaks koodi ümberpaigutamise pärast nii palju muretsema; võin virnast naasmiseks viidata algsele asukohale, selle asemel et muretseda selle pärast, kus Olen algse koodi suhtes suhteline.)

Kõige esimene asi, mida teie kood peaks tegema, on oleku säilitamine. Võib-olla pusha / pushf? Nüüd töötle ära. Tagastamise asemel peaksid teie koodi viimased baidid tegema järgmist.

  • Pange lipud ja registrid sisse
  • kopeerige baitidesse teie algsest koodist varem üle kirjutanud
  • kerige pinu lahti, kohandades SP kõne või kaugkõne arvestamiseks
  • jmp või far jmp IP või CS: IP vahetult praeguse SP-i alla

See protsess on tegelikult peamine viis, kuidas traditsiooniline pahavara teie koodi sisse haakub. Loote omamoodi ümbersõidu.



See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...