fr0st-brutal / delphi_memorymodule Goto Github PK
View Code? Open in Web Editor NEWDelphi adaptation of MemoryModule — load DLL from memory. Also includes hooking utilities.
Delphi adaptation of MemoryModule — load DLL from memory. Also includes hooking utilities.
Undeclared HCUSTOMMODULE (old declaration HMODULE)
I have a valid DLL as 32bit version and 64bit version (LoadLibrary works). Your code works perfect with the 32bit DLL, but when I try to load the 64bit DLL, my application completely crashes when executing
successfull := DllEntry(HINST(code), DLL_PROCESS_ATTACH, nil);
Tested with XE2 and 10.2.
In MemoryModule.pas "procedure FinalizeSections();" can't find ALIGN_DOWN
We can write like this:
for var i := 1 to 10 do
LoadLibrary('test.dll');
In LoadLibrary
was hooked with MemoryModuleHook
, the above code will cause access violation or unexpected errors.
using MemoryModule will cause access violation for large application built with runtime packages.
This happen to FixPtr
function in ExecuteTLS
.
This is due to the code
was allocated via VirtualAlloc
to allocate memory at arbitrary position:
// reserve memory for image of library
// XXX: is it correct to commit the complete memory region at once?
// calling DllEntry raises an exception if we don't...
code := VirtualAlloc(Pointer(old_header.OptionalHeader.ImageBase),
old_header.OptionalHeader.SizeOfImage,
MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE);
if code = nil then
begin
// try to allocate memory at arbitrary position
code := VirtualAlloc(nil,
old_header.OptionalHeader.SizeOfImage,
MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE);
if code = nil then
begin
SetLastError(ERROR_OUTOFMEMORY);
Exit;
end;
end;
And it further affect in ExecuteTLS
:
callback := FixPtr(callback);
I refer to c version of MemoryModule: https://github.com/fancycode/MemoryModule/blob/master/MemoryModule.c
It seems calling FixPtr
isn't require.
An exception raised into ExecuteTLS function:
function ExecuteTLS(Module: PMemoryModule): Boolean;
var
CodeBase: Pointer;
directory: PIMAGE_DATA_DIRECTORY;
tls: PIMAGE_TLS_DIRECTORY;
callback: PPointer; // =^PIMAGE_TLS_CALLBACK;
// TLS callback pointers are VA's (ImageBase included) so if the module resides at
// the other ImageBage they become invalid. This routine relocates them to the
// actual ImageBase.
// The case seem to happen with DLLs only and they rarely use TLS callbacks.
// Moreover, they probably don't work at all when using DLL dynamically which is
// the case in our code.
function FixPtr(OldPtr: Pointer): Pointer;
begin
Result := Pointer(NativeInt(OldPtr) - Module.Headers.OptionalHeader.ImageBase + NativeInt(CodeBase));
end;
begin
Result := True;
CodeBase := Module.CodeBase;
directory := GET_HEADER_DICTIONARY(Module, IMAGE_DIRECTORY_ENTRY_TLS);
if directory.VirtualAddress = 0 then
Exit;
tls := PIMAGE_TLS_DIRECTORY(PByte(CodeBase) + directory.VirtualAddress);
// Delphi syntax is quite awkward when dealing with proc pointers so we have to
// use casts to untyped pointers
callback := Pointer(tls.AddressOfCallBacks);
if callback <> nil then
begin
--------------------------------------------------------------------------
callback := FixPtr(callback);
while callback^ <> nil do
--------------------------------------------------------------------------
begin
PIMAGE_TLS_CALLBACK(FixPtr(callback^))(CodeBase, DLL_PROCESS_ATTACH, nil);
Inc(callback);
end;
end;
end;
Hello,
Please not that finalization caused an access violation when invoking MemoryFreeLibrary.
All library calls are redirected and well executed.
procedure InstallModule;
begin
if Assigned(ModuleList) or IsDesigntime then Exit;
ModuleList := TKeyRecord<TMemoryModule>.Create;
ModuleMemory := MemoryLoadLibary(ExtractResource('MEMORYMODULE.DLL'));
LoadLibraryMemory := MemoryGetProcAddress(ModuleMemory,'LoadLibraryMemory');
FreeLibraryMemory := MemoryGetProcAddress(ModuleMemory,'FreeLibraryMemory');
OldLoadLibraryA := HookProcedure(@LoadLibraryA,@LoadLibraryAHooked,LoadLibraryAHook);
OldLoadLibraryW := HookProcedure(@LoadLibraryW,@LoadLibraryWHooked,LoadLibraryWHook);
OldLoadLibrary := HookProcedure(@LoadLibrary,@LoadLibraryWHooked,LoadLibraryHook);
OldLoadLibraryExA := HookProcedure(@LoadLibraryExA,@LoadLibraryExAHooked,LoadLibraryExAHook);
OldLoadLibraryExW := HookProcedure(@LoadLibraryExW,@LoadLibraryExWHooked,LoadLibraryExWHook);
OldLoadLibraryEx := HookProcedure(@LoadLibraryEx,@LoadLibraryExWHooked,LoadLibraryExHook);
OldFreeLibrary := HookProcedure(@FreeLibrary,@FreeLibraryHooked,FreeLibraryHook);
UnregisterExpectedMemoryLeak(ModuleMemory);
end;
procedure UnhookModule;
begin
UnhookProcedure(LoadLibraryAHook);
UnhookProcedure(LoadLibraryWHook);
UnhookProcedure(LoadLibraryHook);
UnhookProcedure(LoadLibraryExAHook);
UnhookProcedure(LoadLibraryExWHook);
UnhookProcedure(LoadLibraryExHook);
UnhookProcedure(FreeLibraryHook);
end;
initialization
InstallModule;
finalization
if Assigned(ModuleList) then
begin
UnhookModule;
FreeAndNil(ModuleList);
end;
if Assigned(ModuleMemory) then MemoryFreeLibrary(ModuleMemory);
end.
If the Library not freed than a memory leak will be generated.
Best regards.
I have a simple InstallHook that perform nothing:
function MyHook(lpLibFileName: PWideChar): Pointer;
begin
Result := nil;
end;
initialization
InstallHook(MyHook);
finalization
UninstallHook;
end.
When launch the application build with Win64 platform, it raise A call to an OS function failed
error.
The above code works on Win32 build.
InstallHook will intercept LoadLibrary
, GetProcAddress
and FreeLibrary
. The function fail to work for application built with runtime packages.
Delphi 10.1 berlin
Calling raised exception at GetProcAddress_Internal(handle, PAnsiChar(IMAGE_ORDINAL(thunkRef^))) instruction
while thunkRef^ <> 0 do begin if IMAGE_SNAP_BY_ORDINAL(thunkRef^) then funcRef^ := GetProcAddress_Internal(handle, PAnsiChar(IMAGE_ORDINAL(thunkRef^))) else begin thunkData := PIMAGE_IMPORT_BY_NAME(PByte(codebase) + thunkRef^); funcRef^ := GetProcAddress_Internal(handle, PAnsiChar(@(thunkData.Name))); end; if funcRef^ = nil then begin Result := False; Break; end; Inc(funcRef); Inc(thunkRef); end; // while
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.