Wie schwer ist es (wirklich), Assembler-Code zu dekompilieren? [closed]

Lesezeit: 4 Minuten

Benutzeravatar von lindelof
Lindelof

Ich versuche harte Fakten zu finden, die meinem Management helfen zu verstehen, wie schwer/einfach es ist, kompilierten C-Code zurückzuentwickeln.

Ähnliche Fragen wurden bereits früher auf dieser Seite gestellt (siehe z. B. Ist es möglich, eine Windows-.exe zu „dekompilieren“? Oder zumindest die Assembly anzuzeigen? oder Ist es möglich, eine in C geschriebene DLL zu dekompilieren?), aber der Kern dieser Fragen ist das Das Dekompilieren von kompiliertem C-Code ist “hart, aber nicht ganz unmöglich”.

Um Antworten zu erleichtern, die auf Fakten basieren, füge ich kompilierten Code für eine Mystery-Funktion hinzu und schlage vor, dass Antworten auf diese Frage den Erfolg oder Misserfolg der vorgeschlagenen Techniken daran messen, ob sie bestimmen können, was diese Funktion tut. Dies mag für SO ungewöhnlich sein, aber ich denke, es ist der beste Weg, um “gute subjektive” oder sachliche Antworten auf diese technische Frage zu erhalten. Deswegen, Was ist Ihre beste Vermutung darüber, was diese Funktion macht und wie?

Dies ist der kompilierte Code, kompiliert auf Mac OSX mit gcc:

_mystery:
Leh_func_begin1:
    pushq   %rbp
Ltmp0:
    movq    %rsp, %rbp
Ltmp1:
    movsd   LCPI1_0(%rip), %xmm1
    subsd   %xmm0, %xmm1
    pxor    %xmm2, %xmm2
    ucomisd %xmm1, %xmm2
    jbe     LBB1_2
    xorpd   LCPI1_1(%rip), %xmm1
LBB1_2:
    ucomisd LCPI1_2(%rip), %xmm1
    jb      LBB1_8
    movsd   LCPI1_0(%rip), %xmm1
    movsd   LCPI1_3(%rip), %xmm2
    pxor    %xmm3, %xmm3
    movsd   LCPI1_1(%rip), %xmm4
    jmp     LBB1_4
    .align  4, 0x90
LBB1_5:
    ucomisd LCPI1_2(%rip), %xmm1
    jb      LBB1_9
    movapd  %xmm5, %xmm1
LBB1_4:
    movapd  %xmm0, %xmm5
    divsd   %xmm1, %xmm5
    addsd   %xmm1, %xmm5
    mulsd   %xmm2, %xmm5
    movapd  %xmm5, %xmm1
    mulsd   %xmm1, %xmm1
    subsd   %xmm0, %xmm1
    ucomisd %xmm1, %xmm3
    jbe     LBB1_5
    xorpd   %xmm4, %xmm1
    jmp     LBB1_5
LBB1_8:
    movsd   LCPI1_0(%rip), %xmm5
LBB1_9:
    movapd  %xmm5, %xmm0
    popq    %rbp
    ret 
Leh_func_end1:

AKTUALISIEREN

@Igor Skochinsky ist der erste, der die richtige Antwort findet: Es ist in der Tat eine naive Implementierung von Herons Algorithmus zur Berechnung von Quadratwurzeln. Der Original-Quellcode ist hier:

#include <stdio.h>

#define EPS 1e-7

double mystery(double x){
  double y=1.;
  double diff;
  diff=y*y-x;
  diff=diff<0?-diff:diff;
  while(diff>=EPS){
    y=(y+x/y)/2.;
    diff=y*y-x;
    diff=diff<0?-diff:diff;
  }
  return y;
}

int main() {
  printf("The square root of 2 is %g\n", mystery(2.));
}

  • Du hast 7k+ Ruf und sprichst “die Site-Moderatoren” an?? Haben Sie nicht herausgefunden, wie diese Seite funktioniert?

    – Kerrek SB

    13. Januar 2013 um 21:53 Uhr

  • @djechlin: Wie ist “Rate mal, was mein Assembler macht?” jemals eine berechtigte Frage? (oder war das Sarkasmus?)

    – Oliver Charlesworth

    13. Januar 2013 um 22:07 Uhr


  • @lindelof – Ich gebe Ihnen hier ein weiteres Beispiel, bei dem 10 Zeilen mit eingebetteten Funktionen und C++-Vorlagen in 4-5 Maschinenanweisungen kompiliert werden. Wie stehen die Chancen, dass jemand den ursprünglichen Quellcode reproduzieren kann?

    – Bo Persson

    13. Januar 2013 um 23:33 Uhr

  • Im Allgemeinen ist es unmöglich, die Originalquelle ist absolut unmöglich, in seltenen Fällen, in denen kein Optimierer verwendet wurde und der Code so trivial war, dass Sie sich nicht die Mühe machen müssen, zu C zurückzukehren, dann könnten Sie etwas rekonstruieren, das funktional gleich ist.

    – Oldtimer

    14. Januar 2013 um 4:26 Uhr

  • Stellen Sie sich vor, Sie konvertieren eine WAV-Datei in eine MP3-Datei (ein Bild in JPG, einen Film in MPEG usw.), eine verlustbehaftete Komprimierung. Sie können das ursprüngliche Signal nicht zurückerhalten. Dasselbe passiert im Compiler, Informationen aus dem zu kompilierenden Quellcode gehen verloren, sind in der Ausgabe nicht sichtbar, Sie können nicht zum Original zurückkehren. Funktional ähnlicher C-Code ist nach Möglichkeit nicht besser lesbar oder wartbar als die Assemblersprache. Sie sind besser dran, wenn Sie Änderungen vornehmen müssen, um dies in asm zu tun, oder C-Code von Hand aus einer Analyse des asm schreiben.

    – Oldtimer

    14. Januar 2013 um 4:28 Uhr

  • Also, was ist Ihre beste Vermutung, was dieser Code ist? tun? Ich denke, Sie brauchen eine Algorithmuserkennung zusätzlich zur Wiederherstellung von Code auf niedriger Ebene. PS: Guter Job Reverse Engineering, wo du hingekommen bist, +1 trotz Schließung 🙂

    – Ira Baxter

    14. Januar 2013 um 23:44 Uhr


  • Sieht aus wie die babylonische Methode der Quadratwurzelberechnung. LCPI1_0 ist die anfängliche Näherung, LCPI1_2 ist Epsilon und LCPI1_3 ist die Konstante 0,5.

    – Igor Skochinsky

    15. Januar 2013 um 10:51 Uhr

  • @IgorSkochinsky Herzlichen Glückwunsch, du hast es geschafft!

    – Lindelof

    15. Januar 2013 um 19:09 Uhr

1433110cookie-checkWie schwer ist es (wirklich), Assembler-Code zu dekompilieren? [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy