Giter Site home page Giter Site logo

delphi_memorymodule's Issues

Application crash with 64bit

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.

Access Violation using MemoryModule for large application built with runtime packages

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.

Acces Violation Exception raised into ExecuteTLS function [callback := FixPtr(callback);]

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;


Access violation

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.

A call to an OS function failed in Win64 build using InstallHook

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.

Access violation inside BuildImportTable procedure

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.