![]() |
IMAGEBASE - wichtiges zu DLL und Co.
Liste der Anhänge anzeigen (Anzahl: 1)
Wenn man eine DLL erstellen möchte, dann steht man unter Anderem vor einer "schwierigen" Entscheidung:
"Wo um Himmels Willen soll ich meine DLL im Speicher ablegen?", oder so ähnlich. Denn vollkommen willkürlich sollte/kann man diese nicht positionieren - vorallem nicht an der Standardadresse $00400000, denn dort liegt meistens schon die EXE rum. Und dann wuseln bestimmt auch noch andere DLL's im selben Adressraum herum, welche entweder schon den gewünschten Bereich belegen, oder welche dann ebenfalls verschoben werden müssen, weil sich die eigene DLL dort breit gemacht hat. Wenn man dann auch noch mehrere DLL's erstellt, welche gleichzeitig in der selben EXE integriert sind, wird es noch besser ... denn dort müßten natürlich all diese DLL's ihr eigenes Fleckchen finden. Zu diesem Thema sei auch gleich mal die OH zitiert. Für diejenigen, denen die OH noch unbekannt sein sollte, diese ist das Teil was aufgeht, wenn man die ersten Menüpunkte des Menüs "Hilfe" in Delphi anklickt. ;) Zitat:
Dabei werden nicht einfach nur die DLL-Daten verschoben, sondern es müssen auch noch alle "hardgecodeten" Pointer, far-Sprungaddressen, ... angepasst werden, da sich ja deren Ziele durch das Verschieben ändern. Daher kann man sich bestimmt auch ganz gut vorstellen, daß man in solch einem Fall mit einigen Einbußen (Rechenzeit...) rechnen muß. Es ist also schon "wichtig", daß man seinen DLL's ein freies Plätzchen sucht. Zitat:
* die ImageBase ist ein 32-bit Pointer, welcher auf das Vielfache von 64 KB beschränkt ist. $xxxx0000 < nur die xxxx sind veränderbar * die möglichen Werte für die ImageBase sind: $00010000 bis $7FFF0000 * es wird von Microsoft am Liebsten gesehn, wenn DLL's in folgendem Bereich abgelegt werden: $40000000 und $7FFFFFFF Leider ist dieses aber noch nicht allen bekannt und es gibt tatsächlich Viele, welche ihren DLL's noch nichtmal ein {$IMAGEBASE} spendieren - wo also die DLL immer "immer" im Adressbereich der EXE (ab $00400000) liegt und somit verschoben würde. Hier ist schonmal eine erste kleine Liste von mehr, oder weniger wichtigen "DLL's".
Code:
$00400000.. Project
$00970000..$009C4FFF XercesXMLDom.dll $009D0000..$00B7BFFF XercesLib.dll $00D20000..$00D2AFFF BorlndMM.dll $1A400000..$1A477FFF UrlMon.dll $32600000..$32777FFF CC3260MT.dll $41D00000.. FNS_UCC.dll $51000000..$5104FFFF DDraw.dll $5B0F0000..$5B123FFF UXTheme.dll $5F0D0000..$5F195FFF OpenGL32.dll $5F1A0000..$5F1B9FFF OLEPro32.dll $62250000..$6226EFFF MAPI32.dll $62E10000..$62E17FFF LPK.dll $63000000..$63094FFF WinINet.dll $68FC0000..$68FDDFFF GLU32.dll $6DA00000..$6DA7BFFF DbgHelp.dll $70D00000..$70E9FFFF GDIPlus.dll $71950000..$71A33FFF ComCtl32.dll $71A80000..$71A90FFF MPR.dll $72F10000..$72F69FFF USP10.dll $73B30000..$73B35FFF DCIMan32.dll $73DC0000..$73DC2FFF LZ32.dll $74CB0000..$74CD0FFF OLEDlg.dll $76240000..$7624EFFF MSASN1.dll $76260000..$762EAFFF Crypt32.dll $76320000..$76324FFF MSImg32.dll $76330000..$76349FFF IMM32.dll $76350000..$76395FFF ComDlg32.dll $76620000..$76704FFF SetupAPI.dll $76730000..$76737FFF SHFolder.dll $76AF0000..$76B1CFFF WinMM.dll $76BB0000..$76BBAFFF PSAPI.dll $76BF0000..$76C1AFFF WinTrust.dll $76C50000..$76C71FFF ImageHlp.dll $76E40000..$76E4CFFF RTUtils.dll $76E70000..$76E99FFF TAPI32.dll $770F0000..$7717AFFF OLEAut32.dll $77180000..$77299FFF OLE32.dll $772A0000..$77302FFF ShlWAPI.dll $773A0000..$77B9DFFF Shell32.dll $77BD0000..$77BD6FFF Version.dll $77BE0000..$77C32FFF MSVCRT.dll $77C40000..$77C7FFFF GDI32.dll $77C90000..$77D04FFF RPCRT4.dll $77D10000..$77D9CFFF User32.dll $77DA0000..$77E39FFF ADVAPI32.dll $77E40000..$77F36FFF Kernel32.dll $77F40000..$77FEFFFF NTDLL.dll Die folgende Prozedur ließt den Speicher der laufenden Anwendung aus und speichert die erstellte Liste in einer Textdatei ab. Diese ist für jene, die selber mal in ihrer Anwendung nachschauen wollen. Als Anhang gibt es diese Prozedur auch nochmal in einer 'netten Unit verpackt. Diese Unit muß als letztes in der Uses-Klausel der DPR eingetragen werden, da ja vor deren Aufruf auch alle anderen DLL's geladen werden müssten. Und wenn man eine, oder mehrere DLL's dynamisch lädt, dann sollte man nach dem Laden dieser DLL's die Prozedur "LogModule" nochmals aufrufen. Werden aber alle DLL's statisch eingebunden (was ja meistens der Fall ist), dann reicht es aus, wenn nur die Unit eingebunden wird, da "LogModule" im Initialization-Abschnitt ebenfalls schon einmal aufgerufen wird.
Delphi-Quellcode:
PS: Als Bonus prüft die Prozedur in der Unit auch noch, ob die gefundene DLL mit einer der oben genannten DLL's und deren dort angegebenen ImageBase übereinstimmt.
// © 1997-2005 by FNS Enterprize's™
// © 2003-2005 by himitsu @ Delphi-PRAXiS Uses Windows, SysUtils; // Diese Units mit in der eigenen Uses-Klausel eintragen, // sofern diese da noch nicht vorhanden sind. Procedure LogModule; Var i, i2: Integer; F: TextFile; SystemInfo: TSystemInfo; MemoryBasicInformation: TMemoryBasicInformation; AllocationBase: Pointer; ModName: AnsiString; Begin AssignFile(F, ParamStr(0) + '.txt'); Rewrite(F); VirtualQuery(Pointer(0), MemoryBasicInformation, SizeOf(MemoryBasicInformation)); AllocationBase := MemoryBasicInformation.AllocationBase; i2 := 0; SetLength(ModName, MAX_PATH); SetLength(ModName, GetModuleFilenameA(THandle(AllocationBase), @ModName[1], MAX_PATH)); GetSystemInfo(SystemInfo); i := SystemInfo.dwPageSize; Repeat VirtualQuery(Pointer(i), MemoryBasicInformation, SizeOf(MemoryBasicInformation)); If MemoryBasicInformation.AllocationBase <> AllocationBase Then Begin If AllocationBase <> nil Then WriteLn(F, '$' + IntToHex(i2, 8) + '..$' + IntToHex(i - 1, 8) + ' ' + ExtractFileName(ModName)); AllocationBase := MemoryBasicInformation.AllocationBase; i2 := i; SetLength(ModName, MAX_PATH); SetLength(ModName, GetModuleFilenameA(THandle(AllocationBase), @ModName[1], MAX_PATH)); End; Inc(i, SystemInfo.dwPageSize); Until i <= 0; If AllocationBase <> nil Then WriteLn(F, '$' + IntToHex(i2, 8) + '..$7FFFFFFF ' + ExtractFileName(ModName)); CloseFile(F); End; // zum Schluß muß jetzt noch, "irgendwo" im Programm, die Prozedur "LogModule" aufgerufen werden. Außerdem wird ebenfalls noch angegeben, ob die gefundene DLL verschoben wurde und wo sie eigentlich abgelegt werden wollte. PSS: Auf die selbe Weiße könnte ein Programm auch nachprüfen, ob eine fremde DLL eingeschleußt wurde (DLL-Injektion). Wenn jemand noch weitere "wichtige" DLL's und deren Addressbereich kennt, oder der Meinung ist, daß sich einige der oben genannten DLL's an einen anderen Plätzchen aufhalten, so möchte er/sie es uns bitte mitteilen. |
DP-Maintenance
Dieses Thema wurde von "Chakotay1308" von "Neuen Beitrag zur Code-Library hinzufügen" nach "Tutorials und Kurse" verschoben.
Eher ein Tutorial |
Re: IMAGEBASE - wichtiges zu DLL und Co.
Liste der Anhänge anzeigen (Anzahl: 2)
Mir ist grad aufgefallen, daß ich seit 'ner ganzen Weile eine EXE dazu hier rumliegen hab, welche andere Programme entsprechend ausließt und anzeigt.
Nja, hier isse also: (ich dachte eigentlich, ich hätte es irgendwo mal mit hochgeladen :oops: ) Anbei auch ein Screenshot vom Firefox ... mal sehn wem auffällt, daß da irgendein Idiot versucht unmassen DLLs mit der selben ImageBase zu laden. |
Re: IMAGEBASE - wichtiges zu DLL und Co.
Ich glaube, das lohnt den Aufwand nicht. Nach einem Servicepack oder Update oder Patch, können die DLLs schon wieder wo anders liegen.
Zitat:
Aber es fehlt ein wichtiger Hinweis bei dir, wenn ich ihn nicht überlesen habe. Um die Adressen innerhalb eines Images zu verschieben, gibt es in jedem Image den sogenannten Realloctable. Es gibt Programme mit denen man diese Tabelle entfernen kann, um die Größe des Images zu reduzieren. Bei Exe-Dateien ist das meist kein Problem, da sie als erstes geladen werden und so die Baseaddress immer frei ist. Bei DLLs ist dies natürlich, wie du erklärt hast, nicht der Fall. Entfernt man aus einer DLL den Realloctable, kann Windows die neuen Adressen innerhalb der DLL nicht neu berechnen und die DLL kann nicht geladen werden. |
Re: IMAGEBASE - wichtiges zu DLL und Co.
Zitat:
|
Re: IMAGEBASE - wichtiges zu DLL und Co.
:shock: Ich muß zugeben, diese Anwendung wurde noch nicht "ausgiebig" unter Win7/Vista getestet.
Wollte sie eigentlich (wenn ich mal die etwas mehr Zeit frei hab) überarbeiten/neu schreiben. Ist ja, wie man eventuell sieht, noch eine "uralte" Delphi 7-Anwendung. Aber ganz im Ernst, ich wüßte jetzt nichtmal wo da ein Fehler in meinem Code sein sollte und schiebe erstmal die Schuld auf Delphi (oder vom wem diese böse DLL stammt) ... mal sehn, ob sich da schnell was ändern läßt. @Luckie: Die Windows-eigenen DLLs liegen vorwiegend in einem eigenem "Bereich" und da sollte man seine EXE/DLL eh nicht reinverlagern. Aber es bringt erstmal grundsätzlich was, wenn man bei einer DLL nicht die selbe ImageBase nutzt, wie für seine Anwendung. außerdem verschieben viele ihre Dateien nicht im RAM, nachdem sie einmal positioniert sind, also dürfte sich garnicht soviel oft ändern. |
Re: IMAGEBASE - wichtiges zu DLL und Co.
Hallo,
als Ergänzung, da sicherlich viele das nicht so mitbekommen haben: Delphi unterstützt natürlich auch ASLR und NX. ![]() Seit dem D2007 Compiler ist auch gerade der Switch für ASLR interessant (Address Space Layout Randomization ab Vista):
Delphi-Quellcode:
Gruß Assertor
{$DYNAMICBASE ON}
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz