Kérdés:
Mi az algoritmus a rekurzív áthaladás szétszereléséhez?
perror
2013-06-26 20:34:43 UTC
view on stackexchange narkive permalink

A bináris kód szétszerelése meglehetősen nehéz téma, de egyelőre csak két (naiv) algoritmust látszik széles körben használni az eszközökben.

  • Linear Sweep : Alapvető algoritmus, amely az összes kód ként megjelölt szakaszt felveszi és szétszedi az utasítások egymás utáni elolvasásával.
  • Rekurzív áthaladás : Finomítsa a lineáris söprést emlékeztetve arra, hogy mikor (és hol) vettek fel egy hívást , és visszatérve az utolsó hívásra , amikor találkozunk egy ret -val.

Ezen algoritmusok leírása meglehetősen homályos. A való életben használt eszközökben kissé finomították őket a szétszerelés pontosságának javítása érdekében.

Például a objdump lineáris seprést végez, de az összes szimbólumból indul (és nem csak a kód -ként megjelölt szakaszok elejéből.

Tehát valaki adhat reálisabb leírást a rekurzív bejárási algoritmusról ( eg mivel az IDAPro kódolja)?

Az IIRC rekurzív áthaladásakor a szétszerelő megpróbálja betartani az összes vezérlésátviteli utasítást - vagyis azonosítani és folytatni a szétszerelést az utasítás különböző lehetséges vezérlési folyamán - nem csak a „hívás” utasításokat.
[Lida] (http://lida.sourceforge.net), amely Bastard [libdisasm] (http://bastard.sourceforge.net/libdisasm.html), [diStorm3] (http://code.google. com / p / distorm /) és a [beaengine] (http://www.beaengine.org) olyan nyílt forráskódú szétszerelő motorok, amelyek rekurzív szétszerelést alkalmaznak. Is: : //dl.acm.org/citation.cfm? id = 948149) Cullen és Saumya által készített durva algoritmus a rekurzív söpörés szétszereléséhez.
Kettő válaszokat:
Igor Skochinsky
2013-06-26 22:00:16 UTC
view on stackexchange narkive permalink

Itt egy nagyon egyszerűsített áttekintés arról, hogy az IDA hogyan csinálja:

  1. adja hozzá az elemzési várólistához a felhasználó által megadott összes ismert belépési pontot vagy címet.
  2. amíg a sor nem üres, írja be a következő címet
  3. kérje a processzor modult az utasítás szétszereléséhez.
  4. kérje a processzor modult az utasítás elemzéséhez. kódoljon keresztreferenciákat az összes lehetséges célpontra
    a legegyszerűbb esetben ez a következő utasítás
    a feltételes ugrásokhoz és hívásokhoz, ez a következő utasítás és a cél
    a közvetett ugrásokhoz - ismeretlen, hacsak nem felismert kapcsoló minta
  5. az összes keresztreferencia még nem elemzett célpontját helyezi a sorba
  6. folytassa a 2. lépéssel

Természetesen a valóságban a dolgok összetettebbek. Először is, nem egy sor van, hanem több. Az SDK auto.hpp:

  //// Ez a fájl olyan funkciókat tartalmaz, amelyek működnek az autoanalyzer // várólistával. Az autoanalizátor akkor működik, ha az IDA nincs elfoglalva // a felhasználói billentyűleütések feldolgozásával .// Az autoanalizátornak több sora van. Minden sornak megvan a prioritása .// A sor címet vagy címtartományt tartalmaz .// A címeket értékeik szerint rendezik .// Az elemző az első sor összes címét feldolgozza, majd // átvált a második várólistára és így be .// A várólisták méretét illetően nincsenek korlátozások .// Az elemző leáll, ha az összes sor üres .//// Ez a fájl olyan funkciókat is tartalmaz, amelyek az IDA status // indikátorral és az autoanalízis indikátorral foglalkoznak. / / Ezekkel a funkciókkal megváltoztathatja az indikátor értékét. konvertálás felfedezetlenné AU_CODE = 20, // 1 konvertálás utasítás AU_WEAK = 25, // 2 átalakítás utasításra (ida döntés)
AU_PROC = 30, // 3 konvertálás eljárásindításra AU_TAIL = 35, // 4 adjon hozzá egy eljárás farok AU_TRSP = 38, // 5 nyomkövetési mutatót (még nem használt) / 7 típusinformációk alkalmazása AU_LIBF = 60, // 8 aláírás alkalmazása az AU_LBF2 = 70 címre, // 9 ugyanaz, második pass AU_LBF3 = 80, // 10 ugyanaz, harmadik pass AU_CHLB = 90, // 11 aláírás fájl betöltése (a fájl nevét külön tároljuk) AU_FINAL = 200; // 12 végleges bérlet  
Tévedek, ha azt mondom, hogy az algoritmus munkalista-megközelítését használja. Mint az adatfolyam-elemzésnél? (Valóban nagyon szép)
PSS
2013-06-27 01:36:03 UTC
view on stackexchange narkive permalink

Úgy döntöttem, hogy válaszomat elküldöm, hogy ne buktassam meg Igor válaszát, hanem hogy kiegészítsem. A bejegyzésének szerkesztése sem volt kényelmes. Elég új vagyok a fórumban, és nem vagyok biztos abban, hogy más tagok hogyan fogják fel.

Van egy kis elmélet, amelyet nemrégiben megtanultam, amelyet szeretnék megosztani. Mindenesetre az The IDA Pro Book -ból (I. rész, 1. szakasz) az IDA Pro-val kapcsolatban vettem át, hogy Recursive Descent Disassembly -t használ. , amely a szabályozási áramlás koncepcióján alapszik. Ennek a megközelítésnek a legfontosabb eleme az egyes utasítások elemzése annak megállapítása érdekében, hogy hivatkoznak-e más helyre. Minden egyes utasítást az EIP-vel való interakció alapján osztályozunk. Számos fő osztályozás létezik:

  1. Szekvenciális folyamatok . Ezek olyan utasítások, amelyek végrehajtást adnak át a következő követendő utasításnak, például: add , mov , push , pop , stb. Ezeket az utasításokat szétbontják a lineáris söprés
  2. Feltételes elágazási utasítások segítségével. Ezek True / False feltételes utasítások, például a je és hasonlók. A feltételes utasítások csak 2 lehetséges végrehajtási ágat kínálnak fel. Ha a feltétel Hamis és az ugrás nem kerül végrehajtásra, a szétszerelő folytatja a lineáris söpörést , és az ugrás cél utasítást hozzáadja a későbbre szétszerelhető halasztott kódok listájához a rekurzív leszármazási algoritmus
  3. Feltétel nélküli elágazási utasítások . Ezek az utasítások különös problémákat okozhatnak a rekurzív leszármazóknak abban az esetben, ha az ugrási célt futás közben számítják ki. A feltétel nélküli ágak nem követik a lineáris áramlást. Ha lehetséges, a szétszerelő megpróbálja hozzáadni a feltétel nélküli ugrás célpontját további elemzés céljából. Ha a cél nincs meghatározva, akkor az adott ágat nem bontják szét.
  4. Funkcióhívási utasítások . A hívási utasításokat többnyire Feltétel nélküli elágazási utasításként kezelik, azzal a várakozással, hogy a végrehajtás visszatérjen a hívást követő utasításhoz, amint a funkció befejeződik. A hívásutasítás célcíme várakozó szétszereléshez sorban áll, és a hívást követő utasítást lineáris söpörésként dolgozzuk fel. Azonban nem mindig lehet meghatározni a hívás célját (pl. call eax ).
  5. Visszaküldési utasítások A visszaküldési utasítások nem tartalmaznak információt a szétszerelő számára arról, hogy mi legyen a következő. A szétszerelők nem tudják feltölteni a visszatérési címet a verem tetejéről. Mindez megállítja a szétszerelõt. Ezen a ponton a szétszerelő az elhalasztott célok mentett listájához fordul, hogy ezt kövesse. Pontosan ezért hívják rekurzívnak.

Összefoglalva: The IDA Pro Book:

A rekurzív leszármazási algoritmus egyik fő előnye, hogy kiválóan képes megkülönböztetni a kódot az adatoktól. Vezérlési folyamat alapú algoritmusként sokkal kevésbé valószínű, hogy az adatértékeket hibásan szétszedik kódként. A rekurzív süllyedés legfőbb hátránya, hogy képtelen követni a közvetett kódutakat, például ugrásokat vagy hívásokat, amelyek mutató táblákat használnak a célcím megkeresésére. Néhány, a kódra mutató mutatók azonosítására szolgáló heurisztika hozzáadásával a rekurzív leszármazó szétszerelők nagyon teljes kódfedést és kiváló kód- és adatfelismerést nyújthatnak.



Ezt a kérdést és választ automatikusan lefordították angol nyelvről.Az eredeti tartalom elérhető a stackexchange oldalon, amelyet köszönünk az cc by-sa 3.0 licencért, amely alatt terjesztik.
Loading...