Frage

Stellen Sie sich vor Sie möchten, dass ein Programm, dass die Tests Funktionen in einer C ++ DLL-Datei schreiben. Sie sollen den Benutzer ermöglichen, eine DLL zu wählen (nehmen wir an, wir sprechen über c ++ dlls). Er sollte eine Liste aller Funktionen, die von der DLL exportierten erhalten kann. Dann sollte der Benutzer in der Lage, eine Funktion aus der Liste zu wählen, manuelle Eingabe eine Liste von Argumenten (die Argumente sind alle Grundtypen, wie int, double, bool oder char-Arrays (zB c-Typ-Strings)) und versuchen, ausführen, um die ausgewählte Funktion mit den spezifizierten Argumenten. Er möchte wissen, ob die Funktion läuft mit den angegebenen Argumenten, oder tun sie es zum Absturz bringen (weil sie die Unterschrift zum Beispiel nicht übereinstimmen).

Das Hauptproblem ist, dass C ++, eine stark typisierte Sprache ist, erfordert, dass Sie die Anzahl und Art des Arguments für einen Funktionsaufruf bei der Kompilierung time.And in meinem Fall zu wissen, habe ich einfach nicht wissen, was diese Argumente , bis der Benutzer wählt sie zur Laufzeit.

Die einzige Lösung, die ich mit kam, war Montag zu verwenden, um manuell die Argumente auf dem Call-Stack drücken.

Aber ich bin gekommen, um zu verstehen, dass, wenn ich mit Montage zu verwirren will, muß ich besser verdammt sicher machen würde, dass ich weiß, welche Aufrufkonvention sind die Funktionen in der DLL verwenden.

So (endlich :) hier meine Frage: kann ich die Aufrufkonvention programmaticaly ableiten? Dependency Walker wird mir nicht helfen, und ich habe keine Ahnung, wie manuell lesen PE-Format.

War es hilfreich?

Lösung

Die Antwort ist vielleicht .

Wenn die Funktionen Namen C ++ eingerichtet, dann können Sie das Argument Anzahl und Typen aus dem Namen Dekoration bestimmen, ist dies Ihr bester Fall und ziemlich wahrscheinlich, wenn MSVC verwendet wurde, den Code in erster Linie zu schreiben.

Wenn die exportierten Funktionen stdcall werden Aufrufkonvention (die Standardeinstellung für Windows-API), können Sie die Anzahl der Bytes bestimmen gedrückt werden, aber nicht die Typen der Argumente.

Die schlechte Nachricht ist, dass für die C-Aufruf-Konvention gibt keine Möglichkeit ist, indem man die Symbolnamen zu erzählen. Sie würden den Zugriff auf den Quellcode oder die Debug-Informationen haben müssen.

http://en.wikipedia.org/wiki/X86_calling_conventions

Der Name, eine Funktion als Export gegeben wird, ist nicht erforderlich , eine Beziehung zu haben, mit dem Namen, dass der Linker sieht, aber die meiste Zeit, die exportierte Namen und den Symbolnamen, dass die Linker sieht gleich sind.

Andere Tipps

Sie hat nicht angegeben, ob Sie sprechen 32-Bit- oder 64-Bit hier, und die von Ihnen skizzierten Schwierigkeiten und die anderen Plakate vor allem auf 32-Bit-Code anzuwenden. Auf 64-Bit-Windows gibt im wesentlichen nur eine Aufrufkonvention ist (es ist in auch in dem Wikipedia-Artikel verknüpft durch John Knoeller), was bedeutet, dass Sie tun kennen die Aufrufkonvention (natürlich mit Ausnahme von jemand kochen ihre eigenen).

Auch mit der Microsoft x64-Aufrufkonvention, nicht die Anzahl der Parameter der Funktion zu wissen, genannt zu werden braucht man nicht davon abhalten es nennen, bietet so viele Parameter, wie Sie wollen / die Benutzerwünsche. Dies liegt daran, dass Sie als ein Anrufer beiseite legen Stapelspeicher und reinigen Sie es danach auf. - Natürlich nicht das Recht, die Bereitstellung [Anzahl] Parameter noch die aufgerufene Funktion tun dumme Dinge haben können, weil Sie ungültige Eingaben sind bereitgestellt, aber das ist eine andere Geschichte

.

Der kompilierte Code nicht einfach sagen: ‚Hier ist diese Funktion ist ein Fastcall, und dies hier ist stdcall‘ leider.

Nicht einmal moderner Disassembler IDA wie try herzuleiten Rufarten standardmäßig (möglicherweise gibt es ein Plugin oder eine Option irgendwo IDK).

Grundsätzlich, wenn Sie ein Mensch sind Sie bei den ersten paar Anweisungen cn und 90% der Zeit erzählen. Wenn sie Pop und Push, seine stdcall, wenn seine params durch die Register (insbesondere ECX), dann seine cdecl vorbei. Fastcall nutzt auch die Register, sondern tut etwas Besonderes .. die Spitze von meinem Kopf weiß nicht ab. Aber all diese Informationen sind nutzlos, weil Ihr Programm wird natürlich kein Mensch sein.

Wenn Sie Tests tun, müssen Sie nicht zumindest die Header-Dateien haben ?? Das ist eine schrecklich harte Weise auf die Haut eine Katze ..

Wenn Sie wissen wollen, was die Aufrufkonvention eines C ++ Funktion verwendet, ist Ihre beste Hoffnung ist, zu studieren

  1. Der Header, der diese Funktion erklärt und
  2. Die Dokumentation für den Compiler, dass Ihr DLL kompiliert.

Aber das Ganze klingt wie ein bisschen ein Durcheinander, ehrlich. Warum hat Ihr Freund möchte in der Lage, dies zu tun, und warum kann er nicht die Informationen bekommen, die er braucht, um einen Header-Parsing, die die entsprechenden Funktionen erklärt?

Diese Seite beschreibt die Art und Weise VC ++ 6 Encodierungen Parameter und Aufrufkonvention Info in einen Symbolnamen: http://www.bottledlight.com/docs/mangle.html

Ich vermute, dass neuere Versionen von VC ++ wird kompatibel sein, aber ich habe nicht bestätigt dies.

Es gibt auch einige Tools, dass dies automatisieren, die die Compiler begleiten: http: //msdn.microsoft.com/en-us/library/5x49w699.aspx

Der Name Mangeln gilt nur für C ++ Funktionen; wenn eine Funktion ‚extern‚C‘‘ dann das wird nicht funktionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top