|
Antwort |
Registriert seit: 16. Feb 2009 82 Beiträge |
#11
Hallo,
es hat sich eine neue Frage ergeben, die ich auch hier: http://www.delphipraxis.net/148977-d...nzubinden.html gepostet habe, da das auch bei Dlls der gleichen Prozessorfamilie bei gleicher Wortbreite interessant ist, zum Beispiel halt für die Kommunikation mit Freepascal Programmen. Die Exporttabelle mit den anzusprechenden Funktionen wird, wie ich bisher verstanden habe durch eine Struktur mit Namen IMAGE_EXPORT_DIRECTORY repräsentiert. Ich kann aber die Adrees dieser Tabelle in den im Netz verfügbaren Dokus nirgends finden. *** Code im verlinkten Beitrag *** Ist vieleicht hier schon in einem Datenfeld die Adresse der Exporttabelle verborgen? Die Struktur der .EXE Datei ist nur bis hierher dokumnentiert. Danach kommen die Section Header. Wo aber ist die Exporttabelle -> IMAGE_EXPORT_DIRECTORY? Geändert von MrSpock ( 5. Dez 2013 um 08:20 Uhr) Grund: Code ist bereits im verlinkten Beitrag. |
Zitat |
Registriert seit: 13. Aug 2002 17.197 Beiträge Delphi 10.4 Sydney |
#12
Wenn Du wissen willst di ein Exe/DLL aufgebaut ist so schau am besten in der MSDN nach
Windows Vista - Eine neue Erfahrung in Fehlern.
|
Zitat |
Registriert seit: 16. Feb 2009 82 Beiträge |
#13
Wenn Du wissen willst di ein Exe/DLL aufgebaut ist so schau am besten in der MSDN nach
Nach PE-Optional-Header folgen mehrere Section-Headers. Meine Frage ist nun: Der wievielte Section Header enthält denn nun die Exporttabelle. Entweder bin ich im englischen nicht fit genug oder ich habe irgenwas noch nicht verstanden. Was ich bisher verstanden habe, ist der grundsätzliche Aufbau des PE Headers. Die Section Headers sind die vorletzten Header, danach folgen die Ressourcen Header (IMAGE_RESOURCE_DIRECTORY). Meine Dll enthält aber keine Ressourcen. Was ich noch nicht rausgekriegt habe, ist, der wievielte Section Header denn nun auf die Exporttabelle zeigt, mit der Struktur IMAGE_EXPORT_DIRECTORY. Wo gibt es dazu detailliertere Auskunft. Die angegebene Doku ist da leider vieeel zu knapp. Warum kann sowas nicht generell detaillierter dokumentiert werden? Wird doch auch von anderen gebraucht, nicht nur hier von mir. Wenn natürlich hier: http://msdn.microsoft.com/en-us/magazine/bb985996.aspx die Sections in derjenigen Reihenfolge beschrieben sind, in der sie in der library abgespeichert sind, dann natürlich habe ich bereits gefunden, wonach ich suche. Werde das gleich mal ausprobieren.
Delphi-Quellcode:
Figure 1 Section Names
Name Description .text The default code section. .data The default read/write data section. Global variables typically go here. .rdata The default read-only data section. String literals and C++/COM vtables are examples of items put into .rdata. .idata The imports table. It has become common practice (either explicitly, or via linker default behavior) to merge the .idata section into another section, typically .rdata. By default, the linker only merges the .idata section into another section when creating a release mode executable. .edata The exports table. When creating an executable that exports APIs or data, the linker creates an .EXP file. The .EXP file contains an .edata section that's added into the final executable. Like the .idata section, the .edata section is often found merged into the .text or .rdata sections. .rsrc The resources. This section is read-only. However, it should not be named anything other than .rsrc, and should not be merged into other sections. .bss Uninitialized data. Rarely found in executables created with recent linkers. Instead, the VirtualSize of the executable's .data section is expanded to make enough room for uninitialized data. .crt Data added for supporting the C++ runtime (CRT). A good example is the function pointers that are used to call the constructors and destructors of static C++ objects. See the January 2001 Under The Hood column for details on this. .tls Data for supporting thread local storage variables declared with __declspec(thread). This includes the initial value of the data, as well as additional variables needed by the runtime. .reloc The base relocations in an executable. Base relocations are generally only needed for DLLs and not EXEs. In release mode, the linker doesn't emit base relocations for EXE files. Relocations can be removed when linking with the /FIXED switch. .sdata "Short" read/write data that can be addressed relative to the global pointer. Used for the IA-64 and other architectures that use a global pointer register. Regular-sized global variables on the IA-64 will go in this section. .srdata "Short" read-only data that can be addressed relative to the global pointer. Used on the IA-64 and other architectures that use a global pointer register. .pdata The exception table. Contains an array of IMAGE_RUNTIME_FUNCTION_ENTRY structures, which are CPU-specific. Pointed to by the IMAGE_DIRECTORY_ENTRY_EXCEPTION slot in the DataDirectory. Used for architectures with table-based exception handling, such as the IA-64. The only architecture that doesn't use table-based exception handling is the x86. .debug$S Codeview format symbols in the OBJ file. This is a stream of variable-length CodeView format symbol records. .debug$T Codeview format type records in the OBJ file. This is a stream of variable-length CodeView format type records. .debug$P Found in the OBJ file when using precompiled headers. .drectve Contains linker directives and is only found in OBJs. Directives are ASCII strings that could be passed on the linker command line. For instance: -defaultlib:LIBC Directives are separated by a space character. .didat Delayload import data. Found in executables built in nonrelease mode. In release mode, the delayload data is merged into another section. Geändert von Nintendo ( 2. Dez 2013 um 11:26 Uhr) |
Zitat |
Registriert seit: 9. Sep 2004 Ort: München 604 Beiträge FreePascal / Lazarus |
#14
es hat sich eine neue Frage ergeben, die ich auch hier: http://www.delphipraxis.net/148977-d...nzubinden.html
gepostet habe, da das auch bei Dlls der gleichen Prozessorfamilie bei gleicher Wortbreite interessant ist, zum Beispiel halt für die Kommunikation mit Freepascal Programmen.
Delphi-Quellcode:
PIMAGE_OPTIONAL_HEADER32 = ^IMAGE_OPTIONAL_HEADER32;
IMAGE_OPTIONAL_HEADER32 = record // // Standard fields. // Magic : WORD; MajorLinkerVersion : BYTE; MinorLinkerVersion : BYTE; SizeOfCode : DWORD; SizeOfInitializedData : DWORD; SizeOfUninitializedData : DWORD; AddressOfEntryPoint : DWORD; BaseOfCode : DWORD; BaseOfData : DWORD; // // NT additional fields. // ImageBase : DWORD; SectionAlignment : DWORD; FileAlignment : DWORD; MajorOperatingSystemVersion : WORD; MinorOperatingSystemVersion : WORD; MajorImageVersion : WORD; MinorImageVersion : WORD; MajorSubsystemVersion : WORD; MinorSubsystemVersion : WORD; Win32VersionValue : DWORD; SizeOfImage : DWORD; SizeOfHeaders : DWORD; CheckSum : DWORD; Subsystem : WORD; DllCharacteristics : WORD; SizeOfStackReserve : DWORD; SizeOfStackCommit : DWORD; SizeOfHeapReserve : DWORD; SizeOfHeapCommit : DWORD; LoaderFlags : DWORD; NumberOfRvaAndSizes : DWORD; //...X.....X... //....X...X.... //.....X.X..... //......X...... //.....X.X..... //....X...X.... //...X.....X... DataDirectory : array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY; end; Ist vieleicht hier schon in einem Datenfeld die Adresse der Exporttabelle verborgen?
Entweder bin ich im englischen nicht fit genug oder ich habe irgenwas noch nicht verstanden.
Was ich bisher verstanden habe, ist der grundsätzliche Aufbau des PE Headers. Die Section Headers sind die vorletzten Header, danach folgen die Ressourcen Header (IMAGE_RESOURCE_DIRECTORY). Meine Dll enthält aber keine Ressourcen. Was ich noch nicht rausgekriegt habe, ist, der wievielte Section Header denn nun auf die Exporttabelle zeigt, mit der Struktur IMAGE_EXPORT_DIRECTORY. Wo gibt es dazu detailliertere Auskunft. Bei der Suche nach dem dort angegebenen Wert in Google kommen dann durchaus noch ein paar Tutorials zum Thema zu Tage... Gruß, Sven
Sven
[Free Pascal Compiler Entwickler] this post is printed on 100% recycled electrons |
Zitat |
Registriert seit: 16. Feb 2009 82 Beiträge |
#15
Zitat von JamesTKirk:
Warum sollte man das brauchen? Free Pascal erzeugt normale Win32/64/CE DLLs, die von jedem anderem Windows Program auch nutzbar sind (zumindest solange man sich daran hält keine FPC spezifischen Typen zu verwenden, aber das gilt analog für Delphi und C++ auch...)
Lizenzrechtlich ist zu sagen, das jeder Herrn Jason Burgon eine Emailschicken kann, mit der Bitte, ihm die GVision zu schicken. Ich hab das per Anfrage wegen des von ihm nicht mehr verfügbaren Vertriebes gemacht, wollte das Paket auch kaufen. Er hat mir dann das Paket kostenlos geschickt. War dazu auf seiner Webseite und habe "Order" angeklickt. Er plant eine Portierung nach Freepascal, aber nur für die Windows Plattform. Um für Go32 die Portierung zu sparen, das Umschreiben des Codes, will ich das Problem per Dll lösen, denn Borland Pascal, das ich besitze, erlaubt das compilieren von Dlls für Dos unter 16Bit DPMI. Die damit verbundene Notwendigkeit, mich mit dem Aufbau einer ausführbaren Datei zu beschäftigen, hilft mir vielleicht später bei anderen Programmprojekten. Das bloße Umschreiben von DOS Code hilft mir dagegen weniger, außer natürlich betreffs Assembler, denn wegen der anderen Wortbreite müssen die Assemblerteile angepasst werden. Ich fühle mich aber nicht fit genug dafür, da sich die Assembler Syntax doch von der in BPascal unterscheidet. Wäre höchstens ein Versuch Wert mit Freepascal bis 1.9.2. Dieser Compiler konnte noch den 16 Bit Assemblercode einfach lesen und in passende 32 Bit Befehle übersetzen. Leider machen das spätere FPC Compiler nicht mehr so einfach. Aber ich habe noch so einen alten FPC Compiler im Netz gefunden. Wegen Opensource mache ich mir da momentan wenig Sorgen, da Herr Burgon bei höflicher Anfrage kulant ist und die Graphic Vision dem Interessenten zusendet, womit dieser Interessent dann auch den Quellcode hat. Allerdings nur wenn er den korrekt installiert. Dazu ist dann allerdings eine legale Borland Pascal Distri erforderlich, weil nur da die Quellcodes der Laufzeitbibliotheken dabei sind, die zur Installation der Quellcodes Voraussetzung sind. Zur Not könnte man sich aber vielleicht mit der Kenntnis der Baumstruktur der Directories behelfen. Es gibt Borland Pascal zum Download im Internet. Wie legal das da ist, weiß ich nicht. Ich habe aber mehrmals Borland, wie auch Emba auf diese Downloads hingewiesen aber nie eine Antwort erhalten. Die Downloadlinks funktionieren noch immer. Wenn also der Eigentümer die Situation duldet....? Habe zudem in einem Internetforum gelesen, das man wohl bei Emba oder Borland höflich anfragen kann und dann auf Wunsch das Paket zugesendet bekommt. Möglicherweise völlig kostenlos. Das wäre dann der völlig legale Weg. Aus diesen Gründen bevorzuge ich das Schreiben einer Unit, die meine spätere Dll in den Speicher liest, Das Wissen zum Aufbau der Exe dürfte auch in anderer Hinsicht in der Windows Programmierung nützlich sein. Diese Unit soll auch den Code zum Aufruf meiner Dll Funktionen enthalten. Aktuell allerdings habe ich mir zum Testen erst mal eine 32 Bit Dll mit einer einzigen Exportfunktion geschrieben.
Delphi-Quellcode:
library Test32dll;
//Uses Klausel wie vom Delphi Dll Experten eingerichtet function helloWorld; stdcall; begin Writeln('Hello World from a DLL!'); Writeln('Zurück mit <<ENTER>>... '); Readln; end; exports helloWorld;
Delphi-Quellcode:
Und hier noch mein Testprogramm:
unit ULoadDll;
interface uses Windows; { wegen VirtualAlloc() } (* MemoryModule.h *) const { ERROR_RESOURCE_DATA_NOT_FOUND = ERROR_RESOURCE_LANG_NOT_FOUND = ERROR_RESOURCE_NAME_NOT_FOUND = ERROR_RESOURCE_TYPE_NOT_FOUND = } IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16; IMAGE_SIZEOF_SHORT_NAME = 8; { Indizes in Sections Array } IMAGE_DEFAULT_CODE = 0; IMAGE_DEFAULT_DATA_READWRITE = 1; IMAGE_DEFAULT_DATA_READONLY = 2; IMAGE_IMPORT_TABLE = 3; IMAGE_EXPORT_TABLE = 4; //meine Funktionen IMAGE_RESOURCE_TABLE = 5; IMAGE_UNINITIALIZED_DATA = 6; IMAGE_CPP_RUNTIME_SUPPORT = 7; IMAGE_DATA_THREAD_LOCAL_STORAGE = 8; IMAGE_BASE_RELOCATIONS = 9; IMAGE_SDATA_FORIA64_ONLY = 10; IMAGE_SRDATA_FORIA64_ONLY = 11; IMAGE_PDATA_FORIA64_ONLY = 12; IMAGE_DEBUG_CODEVIEW_SYMBOLS = 13; IMAGE_DEBUG_CODEVIEW_TYPERECORDS = 14; IMAGE_DEBUG_PRECOMPILED_HEADERS = 15; IMAGE_CONTAINS_LINKER_DIREKTIVES = 16; IMAGE_DELAY_LOAD_IMPORT_DATA = 17; type HMEMORYMODULE = Pointer; HMEMORYRSRC = Pointer; HCUSTOMMODULE = Pointer; LPVOID = Pointer; LPCTSTR = PChar; LPTSTR = PChar; PUINT = ^UINT; UINT = Longint; PULONG = ^ULONG; ULONG = LongWord; { in delphi 3 -> Longint } PDWORD = ^DWORD; DWORD = LongWord; { in delphi 3 -> Longint } PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER; IMAGE_DOS_HEADER = record // DOS .EXE header e_magic : WORD; // Magic number { MZ for exe } e_cblp : WORD; // Bytes on last page of file e_cp : WORD; // Pages in file e_crlc : WORD; // Relocations e_cparhdr : WORD; // Size of header in paragraphs e_minalloc : WORD; // Minimum extra paragraphs needed e_maxalloc : WORD; // Maximum extra paragraphs needed e_ss : WORD; // Initial (relative) SS value e_sp : WORD; // Initial SP value e_csum : WORD; // Checksum e_ip : WORD; // Initial IP value e_cs : WORD; // Initial (relative) CS value e_lfarlc : WORD; // File address of relocation table e_ovno : WORD; // Overlay number e_res : array[0..3] of WORD; // Reserved words e_oemid : WORD; // OEM identifier (for e_oeminfo) e_oeminfo : WORD; // OEM information; e_oemid specific e_res2 : array[0..9] of WORD; // Reserved words e_lfanew : Longint; // File address of new exe header end; PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER; IMAGE_FILE_HEADER = record Machine : WORD; NumberOfSections : WORD; TimeDateStamp : DWORD; PointerToSymbolTable : DWORD; NumberOfSymbols : DWORD; SizeOfOptionalHeader : WORD; Characteristics : WORD; end; TLocation = record case DWORD of 0: (PhysicalAddress: DWORD); 1: (VirtualSize: DWORD); end; IMAGE_SECTION_HEADER = record Name : array[0..IMAGE_SIZEOF_SHORT_NAME-1] of BYTE; Misc : TLocation; VirtualAddress : DWORD; SizeOfRawData : DWORD; PointerToRawData : DWORD; PointerToRelocations: DWORD; PointerToLinenumbers: DWORD; NumberOfRelocations : WORD; NumberOfLinenumbers : WORD; Characteristics : DWORD; end; PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY; IMAGE_DATA_DIRECTORY = record VirtualAddress: DWORD; Size: DWORD; end; PIMAGE_BASE_RELOCATION = ^IMAGE_BASE_RELOCATION; IMAGE_BASE_RELOCATION = record VirtualAddress: DWORD; SizeOfBlock: DWORD; end; PIMAGE_OPTIONAL_HEADER32 = ^IMAGE_OPTIONAL_HEADER32; IMAGE_OPTIONAL_HEADER32 = record // // Standard fields. // Magic : WORD; MajorLinkerVersion : BYTE; MinorLinkerVersion : BYTE; SizeOfCode : DWORD; SizeOfInitializedData : DWORD; SizeOfUninitializedData : DWORD; AddressOfEntryPoint : DWORD; BaseOfCode : DWORD; BaseOfData : DWORD; // // NT additional fields. // ImageBase : DWORD; SectionAlignment : DWORD; FileAlignment : DWORD; MajorOperatingSystemVersion : WORD; MinorOperatingSystemVersion : WORD; MajorImageVersion : WORD; MinorImageVersion : WORD; MajorSubsystemVersion : WORD; MinorSubsystemVersion : WORD; Win32VersionValue : DWORD; SizeOfImage : DWORD; SizeOfHeaders : DWORD; CheckSum : DWORD; Subsystem : WORD; DllCharacteristics : WORD; SizeOfStackReserve : DWORD; SizeOfStackCommit : DWORD; SizeOfHeapReserve : DWORD; SizeOfHeapCommit : DWORD; LoaderFlags : DWORD; NumberOfRvaAndSizes : DWORD; DataDirectory : array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY; end; PIMAGE_NT_HEADERS32 = ^IMAGE_NT_HEADERS32; IMAGE_NT_HEADERS32 = record Signature : DWORD; FileHeader : IMAGE_FILE_HEADER; OptionalHeader : IMAGE_OPTIONAL_HEADER32; end; TThunkCharacterisics = record case DWORD of 0: (Characteristics : DWORD); { 0 for terminating null import descriptor } 1: (OriginalFirstThunk: DWORD); { RVA to original unbound IAT (PIMAGE_THUNK_DATA) } end; PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR; IMAGE_IMPORT_DESCRIPTOR = record Thunk : TThunkCharacterisics; TimeDateStamp : DWORD; { 0 if not bound, } { -1 if bound, and real date\time stamp } { in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) } { O.W. date/time stamp of DLL bound to (Old BIND) } ForwarderChain : DWORD; { -1 if no forwarders } Name : DWORD; FirstThunk : DWORD; { RVA to IAT (if bound this IAT has actual addresses) } end; TCode = record case LongWord of 0 : (Offset,Segment: Word); 1 : (LinearAddr: LongWord); end; PIMAGE_EXPORT_DIRECTORY = ^IMAGE_EXPORT_DIRECTORY; IMAGE_EXPORT_DIRECTORY = record Characteristics : DWORD; TimeDateStamp : DWORD; MajorVersion : WORD; MinorVersion : WORD; Name : DWORD; Base : DWORD; NumberOfFunctions : DWORD; NumberOfNames : PDWORD; AddressOfFunctions : PDWORD; { RVA from base of image } AddressOfNames : PDWORD; { RVA from base of image } AddressOfNameOrdinals : PDWORD; { RVA from base of image } end; TSections = Array[0..17] of IMAGE_SECTION_HEADER; PDllFileStruct = ^TDllFileStruct; TDllFileStruct = record dosheader : IMAGE_DOS_HEADER; dosStub : array [0..27] of Byte; peHeader : IMAGE_NT_HEADERS32; SectionHeader: IMAGE_SECTION_HEADER; Code : array of Byte; end; PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY; IMAGE_RESOURCE_DIRECTORY_ENTRY = record Name: DWORD; OffsetToData: DWORD; end; PIMAGE_RESOURCE_DATA_ENTRY = ^IMAGE_RESOURCE_DATA_ENTRY; IMAGE_RESOURCE_DATA_ENTRY = record OffsetToData: ULONG; Size : ULONG; CodePage : ULONG; Reserved : ULONG; end; PIMAGE_RESOURCE_DIR_STRING_U = ^IMAGE_RESOURCE_DIR_STRING_U; IMAGE_RESOURCE_DIR_STRING_U = record Length: WORD; NameString: array[0..1] of WORD; { WCHAR -> 16 Bit UNICODE-CHAR } end; PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY; IMAGE_RESOURCE_DIRECTORY = record Characteristics: DWORD; TimeDateStamp: DWORD; MajorVersion: WORD; MinorVersion: WORD; NumberOfNamedEntries: WORD; NumberOfIdEntries: WORD; { dynamic array } DirectoryEntries: array of IMAGE_RESOURCE_DIRECTORY_ENTRY; { EntryCount is NumberOfIdEntries} end; function LoadLibraryFromFile(Filename: String): TDllFileStruct; function MemoryLoadLibraryEx(var ALibrary: TDllFileStruct): HMEMORYMODULE; procedure MemoryFreeLibrary(var ALibrary: HMEMORYMODULE); (** * Find the location of a resource with the specified type and name. *) function MemoryFindResource(module: HMEMORYMODULE; lpName,lpType: LPCTSTR): HMEMORYRSRC; (** * Find the location of a resource with the specified type, name and language. *) function MemoryFindResourceEx(module: HMEMORYMODULE; lpName,lpType: LPCTSTR; language: WORD): HMEMORYRSRC; (** * Get the size of the resource in bytes. *) function MemorySizeofResource(module: HMEMORYMODULE; resource: HMEMORYRSRC): DWORD; (** * Get a pointer to the contents of the resource. *) function MemoryLoadResource(module: HMEMORYMODULE; resource: HMEMORYRSRC): LPVOID; (** * Load a string resource. *) function MemoryLoadString(module: HMEMORYMODULE; id: UINT; buffer: LPTSTR; maxsize: Longint): Longint; (** * Load a string resource with a given language. *) function MemoryLoadStringEx(module: HMEMORYMODULE; id: UINT; buffer: LPTSTR; maxsize: Longint; language: WORD): Longint; implementation uses {$ifdef DOS} Dos, {$ifdef FPC} Go32, {$else} {$endif} {$endif} SysUtils, Classes; function LoadLibraryFromFile(Filename: String): TDllFileStruct; var S: TFileStream; H: TDllFileStruct; CodeSize: Longint; begin S := TFileStream.Create(Filename, fmOpenRead); S.Read(H, Sizeof(H)-4); CodeSize := S.Size - S.Position; SetLength(H.Code, CodeSize); S.Read(H.Code, CodeSize); S.Free; Result := H; end; const _MEM_COMMIT = $00001000; { Wert zu Windows äquivalent } _MEM_RESERVE = $00002000; { Wert zu Windows äquivalent } _PAGE_NO_ACCESS = $01; { Wert zu Windows äquivalent } _PAGE_READONLY = $02; { Wert zu Windows äquivalent } _PAGE_READWRITE = $04; { Wert zu Windows äquivalent } _PAGE_WRITECOPY = $08; { Wert zu Windows äquivalent } _PAGE_EXECUTE = $10; { Wert zu Windows äquivalent } _PAGE_EXECUTE_READ = $20; { Wert zu Windows äquivalent } _PAGE_EXECUTE_READWRITE = $40; { Wert zu Windows äquivalent } _PAGE_EXECUTE_WRITECOPY = $80; { Wert zu Windows äquivalent } function _VirtualAlloc(DestAddr: Pointer; DestSize: Longint; AllocType, ProtectFlags: DWORD): HMemoryModule; begin //in Freepascal mit GO32 - Memmngr //in Delphi-WDOSX mit DPMI - MemMngr //implementieren end; function MemoryLoadLibraryEx(var ALibrary: TDllFileStruct): HMEMORYMODULE; var Delta : Longint; LibSize: Longint; LibAddr: Longint; AddrPtr: HMemoryModule; EffAddr: Longint; MemSize: Longint; SectionsCount: Integer; begin LibSize := ALibrary.peHeader.OptionalHeader.SizeOfImage; LibAddr := ALibrary.peHeader.OptionalHeader.ImageBase; AddrPtr := VirtualAlloc( Pointer(ALibrary.peHeader.OptionalHeader.ImageBase), ALibrary.peHeader.OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_READWRITE ); EffAddr := Longint(AddrPtr); Delta := EffAddr - ALibrary.peHeader.OptionalHeader.ImageBase; { Dieses Delta muss zu den in den Offsets im File addiert werden } SectionsCount := ALibrary.peHeader.FileHeader.NumberOfSections; Writeln('Anzahl Sectionen: ', SectionsCount); EffAddr := LibAddr + ALibrary.SectionHeader.VirtualAddress; MemSize := ALibrary.SectionHeader.SizeOfRawData; { in Windows: NewAddressPointer := VirtualAlloc(EffAddr, ALibrary.SectionHeader.SizeOfRawData, MEM_COMMIT, RAGE_READWRITE); Aber für DOS32 Schnittstelle muss anderer Weg beschritten werden: } Result := HMEMORYMODULE(EffAddr); //Jetzt muss relocation folgen { Offset := SizeOf(dosheader) + SizeOf(dosStub) + SizeOf(peHeader); Funcns := SizeOf(SectionHeader) * 4 + Offset; } end; procedure MemoryFreeLibrary(var ALibrary: HMEMORYMODULE); begin {HeapFree(GetProcessHeap(), 0, ALibrary);} Dispose(ALibrary); end; const DEFAULT_LANGUAGE = 0; function MemoryFindResource(module: HMEMORYMODULE; lpName,lpType: LPCTSTR): HMEMORYRSRC; begin Result := MemoryFindResourceEx(module, lpName, lpType, DEFAULT_LANGUAGE); end; function _MemorySearchResourceEntry( var root: Pointer; resources: PIMAGE_RESOURCE_DIRECTORY; key: LPCTSTR): PIMAGE_RESOURCE_DIRECTORY_ENTRY; begin end; function MemoryFindResourceEx(module: HMEMORYMODULE; lpName,lpType: LPCTSTR; language: WORD): HMEMORYRSRC; begin end; function MemorySizeofResource(module: HMEMORYMODULE; resource: HMEMORYRSRC): DWORD; begin end; function MemoryLoadResource(module: HMEMORYMODULE; resource: HMEMORYRSRC): LPVOID; begin end; function MemoryLoadString(module: HMEMORYMODULE; id: UINT; buffer: LPTSTR; maxsize: Longint): Longint; begin end; function MemoryLoadStringEx(module: HMEMORYMODULE; id: UINT; buffer: LPTSTR; maxsize: Longint; language: WORD): Longint; begin end; end.
Delphi-Quellcode:
Was mich jetzt wundert, ist, das bei Anzahl Section für diese kleine Dll, die ich zunächst mit Delphi (Turbo Delphi) geschrieben habe, 25954 Sections angezeigt bekomme. Was stimmt da nicht?
program LoadDll16;
{$APPTYPE CONSOLE} uses SysUtils, ULoadDll, Convert, LibExec in 'LibExec.pas'; var MyLib: TDllFileStruct; MemModul: HMEMORYMODULE; begin { TODO -oUser -cConsole Main : Insert code here } MyLib := LoadLibraryFromFile('Test32dll.dll'); Writeln('Kennzeichen ',WordToHex(MyLib.dosheader.e_magic)); Writeln('Anzahl Sections: ', MyLib.peHeader.FileHeader.NumberOfSections); Writeln('Zurück mit << E N T E R >> ... '); ReadLn; MemModul := MemoryLoadLibraryEx(MyLib); end. Das Programm sollte auch ohne die Unit LibExec übersetzbar sein, falls einer so nett ist, das mal auszuprobieren. LibExec enthält noch mal mit anderen Feldbezeichnern die Headerstrukturen und eine Klassendefinition für das Lesen der Dll. Diese Dinge werden von dem Testprogramm nicht benutzt. Mich wundert die hohe Anzahl Sections. Und das ist wie gesagt, die 32 Bit Dll. Die 16 Bit dll, testweise auch nur mit der Hello World Funktion, zeigt mir Null Sections an. Hat die vielleicht doch einen etwas anderen Aufbau? Geändert von Nintendo ( 6. Dez 2013 um 12:03 Uhr) |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |