[gelöst] Problem mit Proxy-DLL
-
Hallo Jochen,
danke für deine Antwort. Ich habe nun gegen die Runtime statisch gelinkt, aber leider funktioniert es immer noch nicht, TOAD läuft, SQLPlus liefert 998 bei LoadLibrary().
Ich habe mit depends.exe nachgeschaut, ob die Runtime auch wirklich nicht mehr dynamisch hinzugelinkt wird, und das ist auch der Fall.Hmm sonst noch irgendwelche Ideen?
998 heißt ja auch, das nicht alle Ressourcen, die die DLL benötigt, geladen werden konnten. Aber warum geht es dann in einer Applikation, aber nicht in der anderen?
Außerdem laufen ja beide Programme, wenn ich unsere oci.dll wieder herausschmeiße (beide Programme greifen auf die selbe Oracle-Runtime / Umgebung zu).
-
Ich habe nochmal einen Screenshot von depends.exe gemacht, einmal SQLPlus mit originaler oci.dll, und einmal mit unserer Proxy-DLL.
original: http://img59.imageshack.us/img59/7200/sqlplusoriginal.png
proxy: http://img704.imageshack.us/img704/1065/sqlplusproxy.pngKann es eventuell sein, das ich gegen alle Libs, so wie sie in der originalen DLL zu sehen sind, auch linken muss?
Kann SQLPlus irgendwie "merken", das wir nicht die echte DLL sind?
-
Wer liefert den Fehlercode? Du in Deinem Programm, wenn Du die "ooci.dll" laden willst?
-
Ja... ich generiere die Fehlermeldung...
Wenn SQLPlus meine DLL lädt, sehe ich noch die erste MessageBox (Startup), und danach die zweite MessageBox mit dem Errorcode.
Danach fliegt SQLPlus auf die Nase, weil es wohl einen Nullpointer anspricht (klar, LoadLibrary schlug fehl und somit sind die ganzen Funktionspointer nicht gesetzt) und das war es dann. Die letzte MessageBox (Shutdown) sehe ich nicht mehr, da vorher aus dem Programmcode gesprungen wird.
-
Also hat die Fehlermeldung doch gar nichts mit Deiner DLL zu tun, sondern Du kannst die umbenannte DLL nicht laden, oder?
-
Ja, aber ich würde sie ja gerne laden. Und wenn ich meine DLL in TOAD verwende, geht es ja auch (oder in einer Testapplikation).
Nur wenn ich meine Proxy-DLL mit SQLPlus nutze, kann die umbenannte DLL auf einmal nicht mehr geladen werden.
-
Sieht aber so aus als würde die eine Anwednung die DLL finden und die andere eben nicht. Kannst ja mal testweise einen absoluten Pfad zum Laden der ooci.dll angeben. Wenn das funktioniert ist die "Dateisuche" tatsächlich das Problem.
-
Ich gebe doch einen absoluten Pfad an, siehe
http://www.pastebin.ca/1838934Oder meintest du rein zufällig "relativer Pfad"?

-
Er findet vermutlich die mscvr71.dll nicht... leg die mal in das gleiche Verzeichnis wie die DLL.
-
Die liegt in demselben Verzeichnis:
http://img687.imageshack.us/img687/9781/foldert.pngDie war schon bei der SQLPlus Installation dabei.
-
Und wieso lädst Du es dann mit einem absoluten Pfad, wenn eh beide DLLs im gleichen Verzeichnis liegen???
-
Ich hatte vorher einen relativen Pfad, das ging nicht. Also habe ich es danach mit einem absoluten Pfad versucht, was auch nicht ging

Ich habe eben noch einmal mit relativem Pfad probiert, aber es funktioniert leider nicht.
-
Ich habe eben erst gemerkt, das Dependency Walker wohl auch zum Debuggen genutzt werden kann

Jedenfalls habe ich mal einen Trace laufen lassen und folgendes bekommen:
http://img12.imageshack.us/img12/9808/dependserror.pngKann jemand mit den Fehlern was anfangen?
Ich werde das Log auch nochmal posten...
-
Dependency Walker Tracelog:
http://pastebin.ca/1841150
-
Das Problem wird vermutlich sein, dass Du in DllMain, die LoadLibrary Funktion aufrufst!
Das sollte man tunlichst vermeiden! (ist auch irgendwo so dokumentiert).Rufe die "Init" Funktion einfach mal in jeder Funktion auf, dann sollte es gehen...
Oder Du linkst doch gegen all die DLLs, welche die original-DLL auch verwendet!
-
Also ich habe ein globales Objekt, in dem die Funktionspointer geladen werden:
http://www.pastebin.ca/1838934Aber ich habe vorhin noch einen Artikel gefunden, wo stand, das wohl dieses globale Objekt irgendwie auch durch die DllMain()-Methode der Laufzeitbibliothek erstellt... oder so ähnlich, das war ein sehr technischer Artikel

Ok ich werde mal versuchen, in jede der 4000 Methoden folgendes einzubauen:
if (dllObject.hL == NULL) dllObject.hL = LoadLibrary(L"ooci.dll"); if (dllObject.p[xxx] == NULL) dllObject.p[xxx] = GetProcAddress(hL,"funcxxx"); __asm jmp dllObject.p[xxx*4];
-
TheGrudge schrieb:
if (dllObject.hL == NULL) dllObject.hL = LoadLibrary(L"ooci.dll"); if (dllObject.p[xxx] == NULL) dllObject.p[xxx] = GetProcAddress(hL,"funcxxx"); __asm jmp dllObject.p[xxx*4];Ja ich weiß, Schreibfehler
War ja nur ein Beispiel.
Aber leider funktioniert das auch nicht, ich bekomme wieder eine Access Violation, und selbst TOAD, was immer lief, will nun nicht mehr.
-
Hmm es scheint nun zu funktionieren, jedoch sehr instabil. Logging in eine Datei führt schnell zum Absturz (fprintf). Aber immerhin, SQLPlus startet endlich einmal.
-
Warum deklarierst Du die Funktionen nicht ganz normal und rufst diese dann ohne Assembler auf?????
-
Das wird bei 2996 Funktionen recht aufwendig

Ich brauche nur 8 oder 10 Funktionen zu überschreiben, die restlichen 2986 werden einfach durchgeleitet.
Das Codebeispiel ist ja nicht komplett, ich hatte es gekürzt. Da die Signatur der Funktionen ja auch immer variiert, kann man das schlecht generisch erstellen. Mit dem Assembler-Call spare ich mir die Beachtung der Signatur.
Nur bei den 10 interessanten Funktionen muss ich dann die Signatur setzen, den Funktionspointer entsprechend casten und Parameter auswerten.