Kann man von einem in C++ geschriebenen Programm den Quellcode wieder herausfinden auch wenn es schon eine .exe/ dmg Datei ist?

7 Antworten

Nein, aber du kannst trotzdem rausbekommen, was das Programm tut. :)

Dafür gibt es Disassembler und Decompiler.

Disassembler sind am zuverlässigsten und liefern dir ein genaues Listing einer jeden CPU-Instruktion.

Da vorher der C++ Compiler ja den Originalquelltext in eine Reihe von CPU-Instruktionen (Maschinenbefehlen) übersetzt und der Linker diese mit anderen Daten in einer einzigen ausführbaren Datei (z. B. EXE) zusammen gepackt hat, kann man diese Maschinenbefehle relativ leicht in einen Assembler-Quelltext zurück wandeln. (das ist jetzt technisch nicht zu 100% korrekt, sollte aber ausreichen ...)

Dann gibt es noch die oben angesprochenen Decompiler, aber im Gegensatz zu vielen Kompilaten anderer Programmiersprachen, ist es technisch gar nicht möglich, dass so etwas bei C++ erfolgreich einen Quelltext erzeugt, der akzeptabel nahe an das Original ran kommt!

Und zwar gibt es ja bei C++ inline, constexpr, Templates, gefühlt eine Million Optimierungen ... das, was am Ende in deiner EXE-Datei steht, hat nur noch entfernt etwas mit dem Original-Quelltext zu tun. Das gilt insbesondere, wenn man Compilerflags zur Optimierung verwendet.

Fazit: Ja, man kann die Funktionsweise deines Programms nachvollziehen, man kann das Programm sogar modifizieren, aber nicht in C++, sondern in Assembler.

C++ Dekompiler werden alle paar Jahre groß angekündigt, und verpuffen dann wieder. Denn aus nicht vorhandenen Informationen kann man keinen C++ Quelltext herbei zaubern. Es funktioniert zwar irgendwie (!) so la la und auch nur dann, wenn man keine hohen Ansprüche hat, aber ist und bleibt Frickelei auf hohem Niveau. :)

Disassembler gibt es aber viele richtig richtig Gute! Unter Windows immer noch den alten Olly, den relativ einfachen PE-Explorer oder das Flagschiff IDA.

Außerdem bieten fast alle großen C++ Debugger die Möglichkeit, durch einzelne CPU-Instruktionen zu steppen. Unter Windows ist das der WinDBG und unter Linux ist der GDB sehr sehr seeeeeeeeehhhhrrr ultra über mega gut! Dafür braucht die EXE keine Debugging-Symbole und auch gestrippte Dateien funktionieren wunderbar. :)

Debugger sind wie Live-Disassembler mit Speichermanipulation und allem drum und dran. Aber das ist ein sehr großes Thema und ich will das hier nur grob anreißen. (Vermutlich sind Debugger DAS mächtigste Werkzeug von Hackern überhaupt ... verglichen damit ist alles andere nur Beiwerk. Mal abgesehen von einer guten Shell.)

Merke: Man kann deinen Quelltext nicht zurückwandeln, aber man kann einen gleichwertigen Assembler-Quelltext erhalten, der sich mit genügend Übung fast so flüssig wie C++ Quelltext lesen lässt.

Auf Assembler-Ebene kann man sowieso IMMER jeden Quelltext einer jeden Programmiersprache lesen. Es ist nur oft sehr aufwändig und dauert gerne mal 3 Monate, bis man ein Programm versteht. (Stichwort "Kopierschutz") :)

Schönen Abend noch und viel Spaß beim Lernen! :)

oelbart  06.02.2017, 20:36

Man kann deinen Quelltext nicht zurückwandeln, aber man kann einen
gleichwertigen Assembler-Quelltext erhalten, der sich mit genügend Übung
fast so flüssig wie C++ Quelltext lesen lässt.

Das spricht jetzt entweder für Deine Assembler-Künste oder gegen deinen C++ Stil  ;)

2
ralphdieter  06.02.2017, 20:43
@oelbart

Ein echter Programmierer kann in jeder Sprache FORTRAN programmieren :-)

1
TeeTier  06.02.2017, 20:53
@oelbart

Zugegeben, das "fast" ist etwas stark übertrieben. :)

Aber in meinen Projekten baue ich immer auch einen Disassembler in den Buildprozess ein, und schaue mir regelmäßig an, was der Compiler aus meinem C++ zaubert. Damit findet man schnell Dinge, die man "besser" lösen könnte / sollte.

Wenn man dann als Hobby hin und wieder das ein oder andere "Crackme" knackt, hat man (= ich) irgendwann genügend Übung, um selbst Assembler relativ flott verstehen zu können! :)

0
TeeTier  06.02.2017, 20:20

Noch eine Anmerkung: Falls du eine Cygwin-Umgebung benutzt, sind da meines Wissens nach auch die Binutils enthalten.

Das ist ein Haufen mächtiger Werkzeuge, allen voran auch "objdump" womit du Kompilate für X verschiedene Plattformen disassemblieren kannst, u. a. natürlich EXEn und DLLs.

Zum Beispiel speichert dir ...

objdump -d -Mintel foo.exe >foo.asm

... das Disassemblat von foo.exe in foo.asm mit Intel-Syntax. :)

objdump hat noch unzählbar mehr Kommandozeilenflags und Funktionen, aber das war jetzt nur ein Beispiel! :)

1
SoftwareCreator  06.02.2017, 20:20

Wow Respekt einfach nur für die lange Antwort hast aber sehr gut erklärt ^^

2

Im Quellcode werden unter anderem Adressen symbolisch angelegt und erst bei der Compilierung durch feste Werte ersetzt. Die ursprünglichen Symbole, die in ihrer Funktion nur Platzhalter waren, gehen dabei unwiederbringlich verloren. Den ursprünglichen Quellcode kann man auf keinen Fall wiedergewinnen.

Es gibt aber Hilfsmittel, die eine angenäherte Rückübersetzung ermöglichen. Damit kann man die Grundstruktur des Programmes mit viel Fleiß, Ausdauer und natürlich sehr guten Programmierkenntnissen einigermaßen rekonstruieren.

Wenn ein Programm z.B. an einer Stelle die Lizenz-Nr überprüft, so ließe sich damit zumindest herausfinden, wo und wie diese Stelle programmiert ist und auch so manipulieren, dass sie übersprungen wird. Deshalb wird bei manchen kostenpflichtigen Anwendungen auch in den Nutzungsbedingungen ausdrücklich das Recompillieren untesagt.

In der Virenbekämpfung dürfte sowas normale Praxis sein, um die Arbeitsweise eines Schadcodes heauszufinden. Die Ersteller der Viren werden kaum den Source-Code dafür zur Verfügung stellen.

Praktisch hat das Zurückübersetzen keine so große Bedeutung, weil das als zielführende Methode sehr aufwändig ist und umfangreiche Spezialkenntnisse voraussetzt. I

Es gibt bei linux distris passende debugger wie zb gdb mit hilfe von denen du dann sofern beim kompilieren angegeben als zusatzparameter im sourcecode stöbern kannst und laufzeit debugging entspannt durchführen kannst. Villeicht gibts ja sowas auch für windows. Alternativ gibts natürlich noch Assembler aber ich denke dazu muss man ja nichtsmehr sagen

Man kann dekompilieren, aber das Ergebnis wird kein C++-Code sein, sondern Assemblercode oder etwas ähnliches (z.B. ein Pseudocode).

Je nach Optimierung des Compilers können Funktionsnamen erhalten bleiben, das wars aber schon.

Programme, die mehr als "Hello World" enthalten zu dekompilieren, um sie selber weiter zu verwenden, lohnt meist nicht. In der Regel ist eine Nachbildung der Funktionalität mit eigenem Code schneller.

Auf legale weise meist nicht, aber es gibt viele decompiler, die so etwas machen können. Die Struktur, Variablennamen und einige essentielle Sachen verschwinden beim compilen, wodurch du am Ende mit viel Wirrwarr (vorallem bei größeren Projekten) konfrontiert werden solltest.


Schilduin  06.02.2017, 19:23

In Deutschland ist Reverse Engineering legal.

1
wotan38  04.03.2017, 13:34
@Schilduin

Mag sein, aber viele Anbieter von Anwendungen untersagen einem ein Decompilieren in den Nutzungsbedingungen. Eine Zuwiderhandlung, sofern es überhaupt aufkommt und dem rechtemäßigen Besitzer des Programmcodes schadet zustößt, verstößt dann gegen Vertragsrecht. Das ist aber immer noch Zivil- und nicht Strafrecht.

0