Hallo Leute, gibt es eine Möglichkeit eine in C geschriebene .dll, zu der man nichts hat (keinen Code, keine Headerdateien, keine Doku, nichts eben), zu nutzen oder diese zurück in Code zu übersetzen? Grüße
Nein. Zwar kann man mit dumpbin herausfinden, welche Symbole die DLL exportiert, aber das muss kein Klartext sein, und vor allem weiß man dann immer noch nichts über die Argumente der sich hinter den Symbolen verbergenden Funktionen. Und den Quelltext kann man aus Binärcode nicht rekonstruieren, das ist ein bisschen wie der Versuch, aus einem Hamburger eine Kuh zu bauen. Man kann allenfalls den Code disassemblieren, aber dann hat man unkommentierten Assemblerquelltext, aus dem man nur mit sehr, sehr viel Übung und genauer Kenntnis des verwendeten C-Compilers vielleicht vage Rückschlüsse auf das Grundgerüst des verwendeten Quelltextes schließen kann, aber auch nur dann, wenn die DLL ohne Optimierung übersetzt worden sein sollte.
Rufus Τ. F. schrieb: > das ist > ein bisschen wie der Versuch, aus einem Hamburger eine Kuh zu bauen. Das dachte ich mir schon :( Danke für Eure Antworten.
Wenn Du ein Programm hast was die DLL benutzt kannst Du erstmal das probieren http://www.dependencywalker.com/ https://de.wikipedia.org/wiki/Dependency_Walker Aber um die Parameter kommst Du damit auch nicht herum. Die Funktionen werden ja angezeigt oder durchnummeriert. Wenn Funktionsnamen kannst Du daran eventuell erkennen was die benötigen. Hoffnung dafür ist aber nicht sehr groß.
xyz schrieb: > Wenn Funktionsnamen kannst Du daran eventuell erkennen was die > benötigen. > Hoffnung dafür ist aber nicht sehr groß. evtl. google : decorated names google : name mangling Stefan
Rufus Τ. F. schrieb: > Die DLL soll in C geschrieben sein. Wie sieht es denn aus, wenn es C-Code ist, aber mit einem C++-Compiler übersetzt wurde? Greift dann wieder das name mangeling? Oder anders gefragt: Hängt das name mangeling vom Code (main.c vs main.cpp) ab, oder vom Compiler (als Beispiel mal den gcc: gcc vs g++)? Man kann den C++-Compiler ja auch mit der C-Datei füttern.
Wenn C-Code als C-Code übersetzt wird, ist es C-Code. Wenn C-Code "als C++-Code" übersetzt wird, ist es kein C-Code, sondern C++-Code. Und dann wird auch wieder "name mangling" verwendet. Bei einer DLL aber ist "name mangling" ausschließlich dann sinnvoll, wenn diese DLL nur von Programmen genutzt werden soll, die ebenfalls in C++ /mit dem gleichen Compiler/ übersetzt wurden, denn das "name mangling" ist compilerabhängig. Eine mit gcc/g++ erzeugte C++-DLL ist nicht mit einem mit einem MS-Compiler übersetzten C++-Programm verwendbar. Damit DLLs überhaupt noch einen Sinn haben, wird daher oft auf ein portables Interface wert gelegt - und das ist die C-Namenskonvention. Also kein "name mangling", und daher gibt es keine Informationen über die Anzahl und Art der Argumente oder der Rückgabewerte. Wie bereits geschrieben, kann man sich mit dumpbin oder vergleichbaren Werkzeugen die von der DLL exportierten Symbole ansehen.
Rufus Τ. F. schrieb: > Wenn C-Code als C-Code übersetzt wird, ist es C-Code. Wenn C-Code "als > C++-Code" übersetzt wird, ist es kein C-Code, sondern C++-Code. Völlig egal ist da der erzeugte Code nix mit dem Export zu tun hat. > Und dann wird auch wieder "name mangling" verwendet. Bei einer DLL aber > ist "name mangling" ausschließlich dann sinnvoll, wenn diese DLL nur von > Programmen genutzt werden soll, die ebenfalls in C++ /mit dem gleichen > Compiler/ übersetzt wurden, denn das "name mangling" ist > compilerabhängig. Leider ist das so. > Eine mit gcc/g++ erzeugte C++-DLL ist nicht mit einem > mit einem MS-Compiler übersetzten C++-Programm verwendbar. bei bekanntem Interface mit entsprendenden IMPORT Dateien schon. > Damit DLLs überhaupt noch einen Sinn haben, wird daher oft auf ein > portables Interface wert gelegt - und das ist die C-Namenskonvention. > Also kein "name mangling", und daher gibt es keine Informationen über > die Anzahl und Art der Argumente oder der Rückgabewerte. Standard bei MS ist hier allerdings __stdcall und das bedeutet decorated unabhängig von der Sprache in der der Quelltext geschrieben wurde oder dem Compiler mit dem übersetzt wurde. > Wie bereits geschrieben, kann man sich mit dumpbin oder vergleichbaren > Werkzeugen die von der DLL exportierten Symbole ansehen. mein Hinweis sollte jetzt allerdings nicht zu wüsten Spekulationen Anlass geben sondern war einfach als Ergänzung zum Beitrag davor gedacht. Mit der dort empfohlenen depends.exe ist die Frage innerhalb von Sekunden geklärt. Hier könnte man dann, wenn decorated, auch gleich die Parameter und den Rückgabetyp sehen. Stefan
Wenn die dll für stdcall compiliert ist (so üblich in der Windows-Only-Szene) dann muss die aufgerufene Funktion den Stack aufräumen. So kannst du durch Ausprobieren oder Studieren des Disassembly evtl für jede Funktion zumindest relativ einfach ermitteln wie viele Bytes beim Aufruf auf den Stack zu pushen sind, dann hast Du schonmal mit relativ wenig Aufwand eine Unsicherheit komplett eliminiert. Beleibt dann "nur" noch herauszufinden WELCHE Argumente die Funktion genau haben will und welchem Zweck die dienen. Wenn Du keine Erfahrung im Reverse-Engineering von Software hast und nur rudimentäre Kenntnisse in C dann wird das eine sehr sportliche Herausforderung und entweder lässt Du Dir das fürstlich bezahlen (und beauftragst einen externen Spezialisten mit dieser Teilaufgabe) oder wenn das aus rein privatem Interesse und sportlichem Ehrgeiz geschieht dann nimm es zum Anlass die nächsten 2 bis 5 Jahre so tief in den Kaninchenbau einzutauchen wie nur wenige zuvor es je getan haben und Dinge zu lernen die kaum ein Mensch zuvor gelernt hat.
Vielen Dank für eure Antworten. All die Hinweise helfen mir doch sehr weiter. Bernd K. schrieb: > wenn das aus rein privatem Interesse und sportlichem Ehrgeiz geschieht > dann nimm es zum Anlass die nächsten 2 bis 5 Jahre so tief in den > Kaninchenbau einzutauchen wie nur wenige zuvor es je getan haben und > Dinge zu lernen die kaum ein Mensch zuvor gelernt hat. Da ich weder noch Frau noch Kinder habe: Challenge accepted! :)
Welches Problem soll denn die DLL lösen? Vielleicht gibt es ja eine weniger arbeitsintensive und sinnvollere Lösung?
Rufus Τ. F. schrieb: > Die DLL soll in C geschrieben sein. C verwendet kein "name mangling". Das stimmt so nicht ganz. Man kann allerdings den Namen selbst im Idealfall nur wenige Informationen über die Parameter entnehmen. Siehe https://en.wikipedia.org/wiki/Name_mangling#C_name_decoration_in_Microsoft_Windows Bernd K. schrieb: > So kannst du durch Ausprobieren oder Studieren des Disassembly evtl für > jede Funktion zumindest relativ einfach ermitteln wie viele Bytes beim > Aufruf auf den Stack zu pushen sind, Viel einfacher geht es duch Lesen des dekorierten Namens, denn genau das ist die Information, die mit in den Namen reingeschrieben wird. Siehe obigen Link. > Beleibt dann "nur" noch herauszufinden WELCHE Argumente die Funktion > genau haben will und welchem Zweck die dienen. Das ist aber der schwierige Teil.
Im Prinzip geht das schon. Du liest den Exporttable aus, stellst dann mit dem Disassembler Deiner Wahl fest welche Parameter die einzelnen Funktionen gern hätten und kannst dann über LoadLibrary und GetProcAddress die Bibliothek laden und die Einsprungadresse der Funktion rausfinden. Dann halt nur über den so erhaltenen Funktionspointer die Bibliotheksfunktion aufrufen und Du hast was Du willst. Solang Du weisst welche Parameter da wo hin gehören und was die in der Lib bewirken, gar keine große Sache. Wenn nicht, ömm... wie gut bist Du im Lesen von fremdem, disassemblierten Code?
Heinz L. schrieb: > und kannst dann über LoadLibrary und > GetProcAddress die Bibliothek laden und die Einsprungadresse der > Funktion rausfinden. Er kann sich auch nen neuen Header schreiben (wird er eh machen müssen weil er ja nen Platz braucht wo er all die Deklarationen und Erkenntnisse niederschreibt die er beim Reversen herausgefunden hat und die man braucht um sie zu benutzen).
Bernd K. schrieb: > Heinz L. schrieb: >> und kannst dann über LoadLibrary und >> GetProcAddress die Bibliothek laden und die Einsprungadresse der >> Funktion rausfinden. > > Er kann sich auch nen neuen Header schreiben (wird er eh machen müssen > weil er ja nen Platz braucht wo er all die Deklarationen und > Erkenntnisse niederschreibt die er beim Reversen herausgefunden hat und > die man braucht um sie zu benutzen). Dazu bräucht er noch die Import-Library (.lib-File). Gibt es ein Tool, mit dem die nachträglich erstellen kann?
Kaj G. schrieb: > gibt es eine Möglichkeit eine in C geschriebene .dll, zu der man nichts > hat (keinen Code, keine Headerdateien, keine Doku, nichts eben), zu > nutzen oder diese zurück in Code zu übersetzen? Klingt nach einer Firma, die keine vernünftigen Richtlinien für die Erstellung von Software hat. Und Du sollst jetzt aus dem Murks, den ein anderer hinterlassen hat, etwas Vernünftiges machen. Im Wesentlichen richtig?
Fabian O. schrieb: > Dazu bräucht er noch die Import-Library (.lib-File). Gibts Tools dafür. Letztendlich steht da ja nichts drin was nicht auch in der dll stehen würde, keine Ahnung warum MS diese Redundanz erfunden hat.
Kaj G. schrieb: > gibt es eine Möglichkeit eine in C geschriebene .dll, zu der man nichts > hat (keinen Code, keine Headerdateien, keine Doku, nichts eben), zu > nutzen oder diese zurück in Code zu übersetzen? Es gibt Tools wie http://sourceforge.net/projects/exetoc/ und http://www.backerstreet.com/rec/en/screenshots.html Diese Tools können etwas helfen, einen Einstieg zu finden, sind aber teilweise recht alt. Stichwort "C Decompile".
Klaus P. schrieb: > Kaj G. schrieb: >> gibt es eine Möglichkeit eine in C geschriebene .dll, zu der man nichts >> hat (keinen Code, keine Headerdateien, keine Doku, nichts eben), zu >> nutzen oder diese zurück in Code zu übersetzen? > > Es gibt Tools wie http://sourceforge.net/projects/exetoc/ und > http://www.backerstreet.com/rec/en/screenshots.html > > Diese Tools können etwas helfen, einen Einstieg zu finden, sind aber > teilweise recht alt. Stichwort "C Decompile". IDA https://www.hex-rays.com/products/ida/index.shtml würd ich noch in die Runde werfen, ist auch ganz beliebt (und sehr mächtig)
:
Bearbeitet durch User
Fabian O. schrieb: > Dazu bräucht er noch die Import-Library (.lib-File). Gibt es ein Tool, > mit dem die nachträglich erstellen kann? Bei Borland war(ist?) implib dabei. Ist aber IMHO nur für mit Borland erstellten code brauchbar. http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/DE/html/devwin32/implib_xml.html Ansonsten ginge noch .def File mit IMPORT Section Ich würde aber auch wie von Heinz L. vogeschlagen late binding und einen eigenen Header bevorzugen. Stefan
Da fällt mir gerade was ein. Wenn diese ominöse DLL in einem realen Projekt benutzt wird, dann muss der Aufrufer der DLL-Funktionen doch bestimmte Dinge über diese Library wissen. Sonst kann er sie ja nicht benutzen. Kann man somit nicht aus dem aufrufenden Code Rückschlüsse auf die DLL ziehen? Nicht über die Details der Implementierung, aber über die Signatur der darin enthaltenen Funktionen? Und falls kein aufrufender Code vorhanden ist... nun, dann verstehe ich den Sinn des ganzen Threads nicht.
:
Bearbeitet durch User
Mark B. schrieb: > Da fällt mir gerade was ein. Wenn diese ominöse DLL in einem > realen > Projekt benutzt wird, dann muss der Aufrufer der DLL-Funktionen doch > bestimmte Dinge über die DLL wissen (sonst kann er sie nicht benutzen). > > Kann man somit nicht aus dem aufrufenden Code Rückschlüsse über die DLL > ziehen? Nicht über die Details der Implementierung, aber über die > Signatur der darin enthaltenen Funktionen? Man kann (sollte) sich das natürlich auch anschauen. Wenn man bei einer bekannten Anwendung die man laufen lassen kann und ungefähr ahnt was sie gerade macht mit der DLL (oder auch wenn man es zu diesem Zeitpunkt noch nicht ahnt) und die Möglichkeit hat sich das zur Laufzeit am lebenden Objekt im Debugger anzuschauen dann sollte man das natürlich auch tun und als wertvolle Information hinzuziehen. Jeder klitzekleine Brocken an Information an die man irgendwie gelangen kann kann helfen bei so einem Vorhaben.
:
Bearbeitet durch User
Wozu brauchst Du eine .lib? Im Endeffekt läuft's auf folgendes raus: Ein typedef damit der Compiler weiss was er mit dem Funktionspointer machen soll, LoadLibrary und GetProcAddress. In etwa so: typedef void (*myfunctiontype)(int parameter1, int* parameter2, ...): void main(){ plib = LoadLibraryEx ("Wiedasdinghaltheisst.dll"); void myfunctionptr = (myfunctiontype)GetProcAddress(plib, "NamevondemCall"); myfunctionptr(parameter1, parameter2,...); } Zusammenreimen darf der Leser. :) Wesentlich dabei ist halt dass man die Parameter richtig dimensioniert. Welche das sind, welchen Typ die haben und was da rein muss, das erzählt einem die Disassembly.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.