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.