Grundlæggende reverse engineering og binæranalyse · Lektion

Genskabelse af den oprindelige programlogik

Udvikl strategier til at udlede de oprindelige programmeringskonstruktioner på højt niveau og deres hensigt ud fra optimerede binære filer.

Lektion 3 af 411 trin

Genskabelse af den oprindelige programlogik er en gratis Grundlæggende reverse engineering og binæranalyse-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Grundlæggende reverse engineering og binæranalyse, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Grundlæggende reverse engineering og binæranalyse-kurset indeholder 4 lektioner i alt.

Hvad er rekonstruktion af kildelogik?

Ved reverse engineering, især af optimerede binærfiler, er målet ofte at forstå den oprindelige kode på højt niveau. Denne proces kaldes rekonstruktion af kildelogik.

Compilere omdanner menneskeligt læsbar kode til maskininstruktioner. Optimering gør dette vanskeligere ved at omarrangere, forenkle eller endda fjerne dele af den oprindelige logik. Vores opgave er at vende denne proces.

Hvorfor rekonstruktion er udfordrende

Optimeringer kan ændre den måde, velkendte programmeringskonstruktioner ser ud på i assembly, drastisk. For eksempel:

  • Udrulning af løkker: En løkke kan blive til en sekvens af gentagne instruktioner.
  • Funktiones indlejring: En funktions kode indsættes direkte, så kaldet fjernes.
  • Fjernelse af død kode: Ubrugte variabler eller grene forsvinder helt.

Det gør direkte kobling til kildekoden vanskelig og kræver i stedet, at vi identificerer mønstre.

Identifikation af løkkestrukturer

Løkker (for, while, do-while) i sprog på højt niveau bliver til betingede spring og bagudrettede grene i assembly.

Når du rekonstruerer, skal du se efter:

  • En kodeblok, der udføres gentagne gange.
  • En sammenligningsinstruktion, der kontrollerer en løkkebetingelse.
  • En springinstruktion, der går tilbage til begyndelsen af løkkeblokken.
  • En opdateringsinstruktion, f.eks. forøgelse af en tæller.

Eksempel på rekonstruktion af en løkke

Se på en simpel for-løkke. En optimerende compiler kan rulle den ud eller forenkle dens tæller. Det afgørende er at finde den gentagne blok og afslutningsbetingelsen.

Prøv at udlede løkkens formål ud fra operationerne i den:

public class LoopExample {
  public static void main(String[] args) {
    int sum = 0;
    for (int i = 0; i < 5; i++) {
      sum += i;
    }
    System.out.println("Sum: " + sum);
  }
}

Betinget logik (If/Else)

if- og else-sætninger er grundlæggende for programmets kontrolflow. I assembly optræder de typisk som en sammenligning efterfulgt af et betinget spring.

Optimeringer kan samle betingelser eller omarrangere blokke. Se efter:

  • Sammenligningsinstruktioner (f.eks. cmp, test).
  • Betingede springinstruktioner (f.eks. je, jne, jg, jl).
  • To adskilte kodeveje, der udspringer fra ét beslutningspunkt.

Eksempel på betinget logik

Her er en grundlæggende if-else-struktur. I optimeret assembly kan else-grenen ligge direkte efter if-grenen, hvor et ubetinget spring springer over den, hvis if-betingelsen var sand.

public class ConditionalExample {
  public static void main(String[] args) {
    int x = 10;
    if (x > 5) {
      System.out.println("X is greater than 5");
    } else {
      System.out.println("X is not greater than 5");
    }
  }
}

Sådan udleder du funktionssignaturer

Når en funktion kaldes, sendes argumenter, og der forventes en returværdi. Kompilatorer bruger kaldskonventioner til at håndtere dette (f.eks. registre og stacken).

  • Brug af stacken: Se, hvor meget plads der allokeres på stacken før og efter et kald, for at gætte antallet af argumenter.
  • Brug af registre: Bestemte registre (f.eks. RAX/EAX på x86/x64) indeholder ofte returværdier.
  • Parametertyper: Den måde, et argument bruges på i funktionen, kan give et fingerpeg om dets datatype.

Rekonstruktion af datastrukturer

Det er vanskeligt at identificere brugerdefinerede datastrukturer (f.eks. structs eller classes) ud fra assembly, især når optimeringer kan have fladet dem ud.

Se efter:

  • Basispeger + forskydning: Adgange til hukommelsesplaceringer med en fast forskydning fra et basisregister angiver ofte felter i en struktur.
  • Gentagne adgangsmønstre: Lignende instruktionssekvenser, der arbejder på tilstødende hukommelsesplaceringer, kan tyde på et array eller en række strukturmedlemmer.
  • Initialiseringsmønstre: Måden, hukommelsesblokke nulstilles eller kopieres på, kan give et fingerpeg om deres størrelse og anvendelse.

Håndtering af funktioner, der er indlejret

Indlejring af funktioner er en optimering, hvor en funktions krop indsættes direkte i den kaldende kode, så den faktiske kaldinstruktion fjernes. Det forbedrer ydeevnen, men gør rekonstruktion vanskeligere.

  • Du vil ikke se en call-instruktion for indlejrede funktioner.
  • Den indlejrede kode vises som en del af den kaldende funktion.
  • Se efter adskilte kodeblokke, der udfører en bestemt genanvendelig opgave, for at identificere mulige indlejrede funktioner.

Hurtigt tjek: Identificering af konstruktioner

Hvilket assembly-mønster er mest tegn på en løkke?

Opsummering: Strategier til rekonstruktion

At rekonstruere den oprindelige kildelogik fra optimerede binærfiler er detektivarbejde. Vi leder efter mønstre og udleder hensigten.

  • Identificer gentagne kodeblokke og bagudrettede spring for løkker.
  • Find sammenligninger og betingede spring for if/else-logik.
  • Analysér brugen af stack og registre for at udlede funktionsargumenter.
  • Se efter adgange med basispeger + forskydning for at gætte datastrukturer.
  • Vær opmærksom på indlejring, som samler funktionskroppe.

Øvelse og fortrolighed med kompilatoroutput er nøglen til at mestre denne færdighed!

Gratis at komme i gang

Lær Assembly med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
12
Lektioner
48

Ofte stillede spørgsmål

Er lektionen “Genskabelse af den oprindelige programlogik” gratis?

Ja — alle 3 lektioner i læringssporet Grundlæggende reverse engineering og binæranalyse, inklusive “Genskabelse af den oprindelige programlogik”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Grundlæggende reverse engineering og binæranalyse-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Genskabelse af den oprindelige programlogik”?

Udvikl strategier til at udlede de oprindelige programmeringskonstruktioner på højt niveau og deres hensigt ud fra optimerede binære filer. Du øver dig i Grundlæggende reverse engineering og binæranalyse med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Grundlæggende reverse engineering og binæranalyse?

Der kræves ingen tidligere erfaring. Grundlæggende reverse engineering og binæranalyse på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Genskabelse af den oprindelige programlogik”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Grundlæggende reverse engineering og binæranalyse-lektion?

Ja. Alle Grundlæggende reverse engineering og binæranalyse-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Almindelige compileroptimeringer
  2. Analyse af optimeret assembly
  3. Genskabelse af den oprindelige programlogik
  4. Genkendelse af inlining og loop-transformationer
← Tilbage til Grundlæggende reverse engineering og binæranalyse