Spørgsmål:
Hvordan identificeres funktioner i en strippet binær på x86 32bit?
lllllllllllll
2014-07-10 22:44:35 UTC
view on stackexchange narkive permalink

Jeg forsøger at generere en grovkornet Opkaldsgraf baseret på nogle samlingskoder adskilt fra binær på x86 32 bit platform.

Det er meget svært at generere en præcis Ring til graf baseret på ASM-kode, idet jeg tænker på forskellige indirekte kontrolflowoverførsler, så lige nu overvejer jeg kun direkte kontrolflowoverførsel .

Så først prøver jeg at identificere funktioner (start- og slutadresser) i den adskilte samlingskode fra en strippet binær på x86, 32bit.

Lige nu er min plan på en eller anden måde sådan:

Hvad angår startadresserne, kan jeg konservativt overveje, at enhver samlingskode ser sådan ud

  push% ebp  

angiver startadressen af en funktion.

og også kan jeg scanne hele problemet ved at identificere alle -opkald -instruktionerne med destinationen, overvej disse funktionsopkalds destinationer, da alle funktionens startadresse

Problemerne er:

  1. s ome af funktionerne defineret i en binær kaldes måske aldrig.

  2. noget af -opkaldet er optimeret som jump af kompilator (tænker på rekursivt haleopkald)

Med hensyn til slutadressen bliver tingene mere vanskelige, fordi flere ret kunne eksistere i en enkelt funktion ...

Så jeg tænker, at jeg måske konservativt betragter området mellem enhver nærmeste funktionsstartadresse som en funktion ..

Har jeg ret ? Er der nogen bedre løsning ..?

Den nemmeste måde ville sandsynligvis være at få IDA 5.0 (den gratis version) og lade det udføre arbejdet.
Du kan også overveje at bruge radare2. Se spørgsmålet: [Rekursiv adskillelse med Radare2?] (Http://reverseengineering.stackexchange.com/questions/4260/recursive-traversal-disassembling-with-radare2)
To svar:
yaspr
2014-07-11 04:33:03 UTC
view on stackexchange narkive permalink

Omvendt opkaldsgraf eller kontrolflowdiagram for en binær er ikke for svag af hjertet og er stadig et varmt emne for forskere.

Din tilgang ser lovende ud; men desværre for dig vil du snuble over mange barrierer.

En, der følger instruktionerne til call , giver sandsynligvis gode resultater, hvis du analyserer den binære fil statisk. Det eneste problem er, at du nogle gange har indirekte opkald / spring. Betydning, operanden vil være et register, der indeholder måladressen. Dette vil forekomme meget ofte, hvis den oprindelige kildekode til binærfiler blev skrevet i f.eks. C ++ (virtuelle funktioner). En måde at få måladressen til i dette tilfælde er at efterligne eller køre det stykke kode, der beregner det. En anden er at vurdere dens værdi heuristisk (heuristik er helvede).

To, du kan køre din binære fil med flere inputdatasæt og dynamisk udtrække opkaldsgraferne (dette kan udføres ved hjælp af instrumentering). Du kan derefter krydshenvise alle de opnåede opkaldsgrafer ...

Tre, jeg vil anbefale en grundlæggende blok centreret tilgang snarere end en funktionel. Hovedsageligt fordi en funktion er en grundlæggende blok i sig selv, og du har mere held med at finde funktioner på denne måde end at prøve at matche mønstre, der kan skifte fra en compiler til en anden eller fra en version af en compiler til en anden.

Følgende publikationer er ekstremt interessante: [1], [2], [3] og også I vil opfordre dig til at tjekke DynInst og callgrind , hvis du vil lære mere om emnet.

Jeg har haft en vis succes med at følge `opkald`` og udføre (minimal!) Emulering til registerspring. [Se et eksempel på et output-uddrag her] (http://reverseengineering.stackexchange.com/questions/2895/delphi-pascal-try-except-finally-block). Anbefalet online læsning: [Decompiler Design] (http://www.backerstreet.com/decompiler/introduction.htm) - esp. [Basic Block-tilgangen] (http://www.backerstreet.com/decompiler/basic_blocks.php).
Codoka
2020-05-27 12:19:56 UTC
view on stackexchange narkive permalink

Generelt kan løsningerne på dette problem klassificeres i:

  • Heuristik, der matcher mønster. Ligesom hvad du foreslår. For eksempel kan søgning efter push es i binærfunktionen give en (ret) grov tilnærmelse af funktionsstart. Ting er sværere, hvis du ønsker at finde funktionsender.

  • Maskinindlæring. Mønstertilpasning kan automatiseres ved hjælp af maskinindlæring. Der er flere forslag i litteraturen som [ 1], [ 2] og [ 3]. Alt dette forsøger at lære funktionerne på byte-niveau ved start og slutning. Moderne kompilatoroptimeringer gør det dog udfordrende for sådanne tilgange at generalisere til binære filer ud over træningssættet.

  • CFG-baserede teknikker. Dette er den mest lovende tilgang baseret på [ 4] (afsløring: første forfatter her) og samtidig [ 5]. Grundlæggende fortsætter det med (1) direkte opkaldsmålanalyse, (2) CFG-traversal for at lokalisere funktionsender og (3) haleanalyse-målanalyse.

  • Information om opkaldsramme (CFI) poster. Inden du gør noget fancy, skal du tjekke CFI-posterne i sektionen .eh_frame . Der er en god chance for, at funktioner allerede er defineret der. For at dumpe CFI-poster kan du bruge noget som readelf --debug-dump = frames /bin/ls.

Jeg har for nylig besøgte problemet med funktionsidentifikation i dette blog indlæg, hvor jeg giver flere detaljer.

Fedt nok. Tak, fordi du opsummerer problemet på en god måde. Det er 2020 nu, og gå solo for at udgive forskningsartikler om "identificering af funktionsgrænser" er måske ikke så lovende som da jeg sendte dette spørgsmål for fem år siden. Men ja, det er altid rart at se, at binære hackingfolk konstant udforsker og udgiver papirer inden for dette felt.


Denne spørgsmål og svar blev automatisk oversat fra det engelske sprog.Det originale indhold er tilgængeligt på stackexchange, som vi takker for den cc by-sa 3.0-licens, den distribueres under.
Loading...