hikari
hikari

Reputation: 3503

Delphi memory leak in BTMemoryModule

testing for memory leaks with madhi's madExcept, and the unit BTMemoryModule to load DLLs straight to ram from a resource, it's reporting leaks here:

How could this be fixed?

    type: VirtualAlloc  
    address: $71d1000  
    size: 177664  
    access rights: ./.

    main thread ($1134):  
    671cd432 madExcept32.dll madExceptDbg 2511 VirtualAllocCallback  
    006a8694 x.exe BTMemoryModule 196 CopySections  
    006a8cee x.exe BTMemoryModule 418 BTMemoryLoadLibary

    type: VirtualAlloc  
    address: $71d0000  
    size: 262144  
    access rights: ./.

    main thread ($1134):  
    671cd432 madExcept32.dll madExceptDbg 2511 VirtualAllocCallback  
    006a8ca4 x.exe BTMemoryModule 409 BTMemoryLoadLibary

    type: VirtualAlloc  
    address: $71d0000  
    size: 262144  
    access rights: ./.

    main thread ($1134):  
    671cd432 madExcept32.dll madExceptDbg 2511 VirtualAllocCallback  
    006a8c3f x.exe BTMemoryModule 396 BTMemoryLoadLibary
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, BTMemoryModule;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
  public
  end;

Const UnrarLibDLL = 'UNRARDLL';

var
  Form1: TForm1;
  rStream: TResourceStream;
  mp_MemoryModule: PBTMemoryModule;
  mp_DllData: Pointer;
  m_DllDataSize: Integer;

implementation

{$R *.dfm}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if m_DllDataSize > 0 then FreeMemory( mp_DllData );
  if mp_MemoryModule <> nil then BTMemoryFreeLibrary( mp_MemoryModule );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  rStream := TResourceStream.Create( HInstance, UnrarLibDLL, RT_RCDATA );
  try
    m_DllDataSize := rStream.Size;
    mp_DllData    := GetMemory( m_DllDataSize );
    rStream.Read( mp_DllData^, m_DllDataSize );
  finally
    rStream.Free;
  end;

  mp_MemoryModule := BTMemoryLoadLibary( mp_DllData, m_DllDataSize );
end;

end.

How to reproduce:

Upvotes: 1

Views: 749

Answers (1)

buttercup
buttercup

Reputation: 1116

Another company made a working DLL loader that does NOT leak memory. The sources are in IPWCore.pas in IPWork's Internet (Components) Delphi Edition that comes with all versions of Delphi.

interface
uses IPWcore;
...
type
  _FunctionDLL = function: integer; stdcall;

var
  pEntryPoint: Pointer;
  pBaseAddress: Pointer;
  FunctionDLL: _FunctionDLL;

implementation

procedure TYourForm.FormCreate;
var
  hResInfo: HRSRC;
  hResData: HGLOBAL;
  pResData: Pointer;
begin
  hResInfo := FindResource(HInstance, 'EMVDLL', RT_RCDATA);
  hResData := LoadResource(HInstance, hResInfo);
  if hResData = 0 then
    exit;
  pResData := LockResource(hResData);
  if pResData = nil then
    exit;
  
  pBaseAddress := IPWorksLoadDRU(pResData, pEntryPoint);
  @FunctionDLL := IPWorksFindFunc(pBaseAddress, 'Function');
  ...
end;

procedure TYourForm.FormDestroy(Sender: TObject);
begin
  IPWorksFreeDRU(pBaseAddress, pEntryPoint);
  pBaseAddress := nil;
  pEntryPoint := nil;
end;

Upvotes: 1

Related Questions