Forum: PC-Programmierung .dll ohne Code/Header nutzbar?


von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Ida (Gast)


Lesenswert?


von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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.

von xyz (Gast)


Lesenswert?

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ß.

von Stefan (Gast)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stefan schrieb:
> evtl.

Die DLL soll in C geschrieben sein. C verwendet kein "name mangling".

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Stefan (Gast)


Lesenswert?

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

von Bernd K. (prof7bit)


Lesenswert?

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.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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! :)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Welches Problem soll denn die DLL lösen? Vielleicht gibt es ja eine 
weniger arbeitsintensive und sinnvollere Lösung?

von Rolf M. (rmagnus)


Lesenswert?

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.

von Heinz L. (ducttape)


Lesenswert?

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?

von Bernd K. (prof7bit)


Lesenswert?

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).

von Fabian O. (xfr)


Lesenswert?

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?

von Mark B. (markbrandis)


Lesenswert?

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?

von Bernd K. (prof7bit)


Lesenswert?

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.

von Klaus P. (Gast)


Lesenswert?

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".

von Bernd K. (prof7bit)


Lesenswert?

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
von Stefan (Gast)


Lesenswert?

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

von Mark B. (markbrandis)


Lesenswert?

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
von Bernd K. (prof7bit)


Lesenswert?

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
von Heinz L. (ducttape)


Lesenswert?

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
Noch kein Account? Hier anmelden.