stdio.h/msvcrt.dll abändern/rekompilieren möglich?

Habe folgendes Problem: möchte in die Funktion "vsprintf" eine spezielle Zusatzabfrage einbringen. Ist es prinzipiell möglich (speziell unter Windows) eine selbst abgeänderte stdio.h als DLL neu zu kompilieren - von meinem Verständnis her müsste das ja eigentlich gehen, wenn man z.B. einen OpenSource-Code für stdio.h verwendet oder liege ich da komplett falsch?
 
Die stdio.h muss man ja nicht kompilieren. Was neu kompiliert werden muss, ist die zugehörige C-Bibliothek. Sofern du unter Windows die GNU-C-Library (glibc) verwendest, dürfte das kein Problem darstellen. Vergiss aber nicht, dass du dann auch ein neues Bootstrapping des Compilers machen musst, wenn du die libc änderst. Verwendest du allerdings die C-Bibliothek von Microsoft oder Borland, kannst du dieses Vorhaben vergessen, da du an deren Sources nicht rankommen wirst.
 
Hallo,
eine Funktion aus der Lib. abzuändern macht in den meisten Fällen keinen Sinn.
Bau lieber eine Wrapper umzu, der die Abfrage/Überprüfung macht und dann ggf. vsprintf aufruft.
 
Die Wrapper wäre meiner Meinung nach die beste Lösung. Du schreibst z.B deine my_vsprintf().

Eventuell könnte man auch mittels Präprozessor einen kleinen Hack machen, sollte man allerdings nicht tun...
 
noch genauere Beschreibung:

Das Problem besteht darin, dass das Zielprogramm die Funktion vsprintf an einer für mich entscheidenden Stelle aufruft (z.B. Datumsumwandlung vor Datumsvergleich), ich aber im Zielprogramm keine Änderungen machen darf odermöchte. Nach meinem (zugegebenermaßen bescheidenen) Verständnis scheint es mir möglich und legal einwandfrei, die Funktion von vsprintf so abzuändern, dass zum Bsp beim Umwandeln eines speziellen Datums immer ein anderes Datum zurückgegeben wird. Ich müsste dazu nur die DLL, die vsprintf enthält patchen/oder einfach neukompilieren. Was sagt ihr zu dieser Idee?

Heißt "Wrappen" in diesem Zusammenhang Einstiegspunkt von vsprintf umlenken auf meine veränderte Zielfunktion? Kann ich das direkt in der DLL hinkriegen, die dann beim Programmstart mitgeladen wird und meine eigene vsprintf-Erweiterung einfach an das Ende der DLL dranhängen? (wenns irgendwie möglich ist, schaff ich das auch!)

Danke schon mal für eure Super-Tipps
 
RE: noch genauere Beschreibung:

Original von lorelei

Heißt "Wrappen" in diesem Zusammenhang Einstiegspunkt von vsprintf umlenken auf meine veränderte Zielfunktion? Kann ich das direkt in der DLL hinkriegen, die dann beim Programmstart mitgeladen wird und meine eigene vsprintf-Erweiterung einfach an das Ende der DLL dranhängen? (wenns irgendwie möglich ist, schaff ich das auch!)

Danke schon mal für eure Super-Tipps
Du hast dann mehrere Probleme: zum einen ist msvcrt Teil der MS-C-Runtimelibs. Ob es dafür Sourcen gibt, bezweifele ich irgendwie ;). Aber solche Kleinigkeiten wie Datumcheck kann man natürlich auch ohne Source durchführen - jedoch stellen sich da mehrere Hürden auf:

DLLs werden für gewöhnlich von Windows in der Reihenfolge geladen: zuerst Programmordner, dann Windows(samt Unterordnern usw, alle Pfade der Umgebungsvariable PATH werden abgeklappert).
D.h wenn die DLL im Programmordner ist, wird sie beim Start auch geladen und man braucht keine Systemdlls zu überschreiben.
Aber: wird DLL von einem Programm schon genutzt, wird sie für ein zweites nicht mehr neu geladen. Und msvcrt wird vom Explorer genutzt. D.h effektiv bleibt nur die Lösung, die gepatchte DLL anders zu nennen und im Zielprogramm entsprechend den Imports umzubennen (sollte aber problemlos mit einem einfachen Hexeditor möglich sein, insbesondere bei der Voraussetzung, dass Du die kompilierte DLL vorher noch selbst erweitern kannst ;) ). Hast Du Dir schon Gedanken gemacht, wie Du eine Datumsumwandlung relativ einfach von einer anderen Formatierung unterscheiden kannst?
 
Datumsabfrage-Erkennung in vsprintf

Ich dachte daran - nachdem es ein ganz bestimmtes Datum ist, dass es zu erkennen gilt - dass ich einerseits den Übergabeparameter auf Übereinstimmung prüfe und andererseits über den Programmstack (nötigenfalls mit Assembler-Code?) die Aufrufadresse prüfe. Nach meiner bescheidenen Meinung glaube ich, dass ich damit 99.99 Prozent der diesbezüglichen Aufrufe von vsprintf herausfiltern könnte. (Es läuft sonst recht wenig auf dem Rechner!) Dann wäre es ja einfach, dass ich nur im Falle der Umwandlung des entsprechenden Datums diesem Datum einfach 10 Jahre hinzugebe ;) - Liege ich da richtig?

Noch eine blöde Frage zu diesem Thema: Wie oder wo kann man erkennen, mit welchem C-Compiler eine Binärdatei erstellt wurde?

Danke für Eure Hilfe
 
Nach meiner bescheidenen Meinung glaube ich, dass ich damit 99.99 Prozent der diesbezüglichen Aufrufe von vsprintf herausfiltern könnte
Jep, das sollte hinhauen, obwohl ich persönlich nicht der Befürworter solcher "globalen" Eingirffe bin (also globalgenutze DLLs ändern).

Noch eine blöde Frage zu diesem Thema: Wie oder wo kann man erkennen, mit welchem C-Compiler eine Binärdatei erstellt wurde?
Also falls sich dieser nicht irgendwo eindeutig "verewigt" hat, helfen meist PEID und RDG[1] weiter.

[1] RDG Packer Detector http://www.exetools.com/forum/showthread.php?t=10646
 
Programmierübung

Ich mach es nur zum Spaß - es interessiert mich als Programmierübung und um zu sehen, ob so etwas überhaupt möglich ist! Sozusagen einen "legalen" Eingriff in eine fremde Software hinzukriegen, indem man ganz allgemein das "zu Grunde liegende System" (Betriebssystem, bzw. DLLs) verändert. Microsoft wäre so ein Eingriff ja sicherlich gleichgültig, wenn ich es nicht verkaufen würde, sondern es nur für mich selbst mache, oder?

Übrigens: die Grund-Annahme ist, dass ich keinen Zugang zum Source habe und am EXE nichts verändern darf (kein Patch, keine Anhänge usw.) Deswegen wirds wohl nichts mit einer eigenen Datumsfunktion - oder verstehe ich dich da falsch?

Fällt euch für dieses Problem sonst noch eine andere Lösung ein, als die oben skizzierte?

2. Wenn ich mich schlau machen möchte bezüglich des oben beschriebenen Eingriffs in die DLL - ist da das Schlagwort "DLL-Injection" das richtige, oder wie könnte ich im Netz fündig werden?
 
letzendlich manipulierst Du ja bei einer Injection den Programmspeicher. Sonst (DLL Patch) greifst Du in das Programmverhalten ein - an Haarspaltereien lässt sich sicherlich so einiges finden ;).
Außerdem darf man die MS-DLL genausowenig verändern wie irgendeine andere. Wobei mir allerdings noch ein Verfahren bekannt ist:
http://www.osix.net/modules/article/?id=728 (lass Dich nicht vom Titel "neu&schnell" beirren.Ich finde den Favlink nicht mehr und das scheint mir eine vernünftige Kopie des Artiekls zu sein ;) ). Ist sogar recht komfortabel, da man hier gleich in C erweitern kann. Was VIM angeht: wenn man es nicht beherrscht, lässt sich auch ein kleines Programm/Skript schreiben, welches dasselbe macht (daran sollte es also nicht scheitern).
Wobei hier auch ein "Patch" erforderlich ist (die Technik aber trotzdem ganz nett ist).

Was DLL Injektion angeht: Die msvcrt sollte beim Programmstart von Windows-PE-Loader in den virtuellen Speicher eingeblendet werden. D.h die Injektion kann nur die bestehende DLL überschreiben (FreeLibrary sollte imho nicht funktionieren, aber Du kannst es ja testen und berichten ;) )
Da kann man aber auch gleich die DLL im Speicher patchen ;).
 
1. Der genannte Artikel ist ja ein Hit !!!! Danke vielmals !
Soweit ich das jetzt so schnell überblicke, wäre diese Lösung sogar ohne Patch machbar ?! Indem ich einfach die eigene, neue DLL direkt kernel32.dll benenne, und die originale kernel32.dll umbenenne und auf diesen Namen referenziere (immer unter der Voraussetzung, dass ich ungewünschte Seiteneffekte ausschließen kann)

Habe bereits versucht, ob sich kernel32 umbenennen lässt :( Natürlich nicht so einfach - man kann sie zwar umbenennen, aber sofort erzeugt Windows wieder eine neue kernel32.dll mit dem genau gleichen Datum, wie die alte.
=> Das Umbenennen müsste z.B. durch Zugriff auf die Platte über LINUX erfolgen - würde mich interessieren, ob Windows das dann mitbekommt und sich dagegen wehrt ?
(kann das im Moment nicht ausprobieren, da ich dazu ja schon die neue DLL bräuchte)

2. Wie könnte ich unter C, ohne Verwendung von Assembler, auf den Stack der Anwendung zugreifen - um die Aufrufadresse zu checken?

3. Wenn ich die DLL aber nur im Speicher patchen würde, nach dem Laden der Anwendung, hätte das dann auch Auswirkungen auf alle anderen Programme, die diese DLL verwenden? Oder anders gefragt: wird beim Laden eines Programmes eine bereits im Speicher vorhandene DLL richtig in den Speicherbereich kopiert, oder nur das Original "eingeblendet"?
 
1) nein, man benennt die "wrapdll" zum Beispiel als YERNEL32.DLL und patcht im Programm den Import. Andrsherum funktioniert es zwar auch, bei SystemDLLs jedoch eine große Fummelei. Wie gesagt - die Kernel32 wird von so gut wie allen Programmen referenziert und demenstprechend befindet sie sich beim Programmstart im Speicher - wird von PE-Loader nciht mehr geladen.
Ich würde grundsätzlich (auch wenn es nur zum Üben ist) von solchen "unsauberen" Lösungen abraten, wie an SystemDLLs global zu manipuliere ;).


zu 3. Patchen im virtuellen speicher hat grundsätzlich nur Auswirkungen auf die jeweilige Anwendung. Wenn meine organische assoziative Datenbank mich nicht täuscht, erstellt Windows eine "lokale" Kopie der DLL im Speicher, sobald ein Schreibzugriff auf die "non-share-Sektion" der DLL erfolgt. D.h Hooks auf die SystemDLLs haben nur auf eine Anwendung auswirkungen.
Hier könnte sich folgendes Szenario ergeben: Du injiziert eine eigene, in C geschriebene DLL in die laufende Anwendung, die DLL schaut mit LoadLibrary und GetProcAddress(vsprintf, bla) nach, wo sich die Funktion befindet - ab hier kann man einen Callback erstellen oder sonstigen Unfug treiben.
 
C-Funktionen für Auslesen des Programm-Stacks

1. Wenn ich wirklich keine Änderung im Zielprogramm machen möchte, kann ich ja leider den DLL-Aufruf nicht umpatchen - müsste also doch versuchen, die System-DLL zu ersetzen.

Ich weiß, das ist absolut "russisch" und unsicher, aber nach meinen Tests (mit LINUX booten, DLL in System32 durch "Dummy"-Patch der DLL ersetzen, Neustart - LÄUFT !) zumindest theoretisch möglich!

2. bleibt nur noch die eine Frage offen: Welches sind die richtigen C-Funktionen für eine Abfrage des aufrufenden Programms (bzw. Auslesen des Programm-Stacks)
 
Zurück
Oben