从内存中加载DLL DELPHI版

   unit MemLibrary;  
interface  
uses  
Windows;  
  
function memLoadLibrary(pLib: Pointer): DWord;  
function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;  
function memFreeLibrary(dwHandle: DWord): Boolean;  
  
implementation  
procedure ChangeReloc(baseorgp, basedllp, relocp: pointer; size: cardinal);  
type  
    TRelocblock = record  
        vaddress: integer;  
        size: integer;  
    end;  
    PRelocblock = ^TRelocblock;  
var  
    myreloc: PRelocblock;  
    reloccount: integer;  
    startp: ^word;  
    i: cardinal;  
    p: ^cardinal;  
    dif: cardinal;  
begin  
    myreloc := relocp;  
    dif := cardinal(basedllp)-cardinal(baseorgp);  
    startp := pointer(cardinal(relocp)+8);  
    while myreloc^.vaddress <> 0 do  
    begin  
      reloccount := (myreloc^.size-8) div sizeof(word);  
      for i := 0 to reloccount-1 do  
      begin  
        if (startp^ xor $3000 < $1000) then  
        begin  
          p := pointer(myreloc^.vaddress+startp^ mod $3000+integer(basedllp));  
          p^ := p^+dif;  
        end;  
        startp := pointer(cardinal(startp)+sizeof(word));  
      end;  
      myreloc := pointer(startp);  
      startp := pointer(cardinal(startp)+8);  
    end;  
end;  
procedure CreateImportTable(dllbasep, importp: pointer); stdcall;  
type  
    timportblock = record  
          Characteristics: cardinal;  
          TimeDateStamp: cardinal;  
          ForwarderChain: cardinal;  
          Name: pchar;  
          FirstThunk: pointer;  
    end;  
    pimportblock = ^timportblock;  
var  
    myimport: pimportblock;  
    thunksread, thunkswrite: ^pointer;  
    dllname: pchar;  
    dllh: thandle;  
    old: cardinal;  
begin  
    myimport := importp;  
    while (myimport^.FirstThunk <> nil) and (myimport^.Name <> nil) do  
    begin  
      dllname := pointer(integer(dllbasep)+integer(myimport^.name));  
      dllh := LoadLibrary(dllname);  
      thunksread := pointer(integer(myimport^.FirstThunk)+integer(dllbasep));  
      thunkswrite := thunksread;  
      if integer(myimport^.TimeDateStamp) = -1 then  
        thunksread := pointer(integer(myimport^.Characteristics)+integer(dllbasep));  
      while (thunksread^ <> nil) do  
      begin  
        if VirtualProtect(thunkswrite,4,PAGE_EXECUTE_READWRITE,old) then  
        begin  
          if (cardinal(thunksread^) and $80000000 <> 0) then  
          thunkswrite^ := GetProcAddress(dllh,pchar(cardinal(thunksread^) and $FFFF)) else  
          thunkswrite^ := GetProcAddress(dllh,pchar(integer(dllbasep)+integer(thunksread^)+2));  
          VirtualProtect(thunkswrite,4,old,old);  
        end;  
        inc(thunksread,1);  
        inc(thunkswrite,1);  
      end;  
      myimport := pointer(integer(myimport)+sizeof(timportblock));  
    end;  
end;  
  
function memLoadLibrary(pLib: Pointer): DWord;  
var  
DllMain    : function (dwHandle, dwReason, dwReserved: DWord): DWord; stdcall;  
IDH        : PImageDosHeader;  
INH        : PImageNtHeaders;  
SEC        : PImageSectionHeader;  
dwSecCount : DWord;  
dwLen      : DWord;  
dwmemsize : DWord;  
i          : Integer;  
pAll       : Pointer;  
begin  
Result := 0;  
IDH := pLib;  
if isBadReadPtr(IDH, SizeOf(TImageDosHeader)) or (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then  
    Exit;  
INH := pointer(cardinal(pLib)+cardinal(IDH^._lfanew));  
if isBadReadPtr(INH, SizeOf(TImageNtHeaders)) or (INH^.Signature <> IMAGE_NT_SIGNATURE) then  
    Exit;  
// if (pReserved <> nil) then  
//    dwLen := Length(pReserved)+1  
// else  
    dwLen := 0;  
SEC := Pointer(Integer(INH)+SizeOf(TImageNtHeaders));  
dwMemSize := INH^.OptionalHeader.SizeOfImage;  
if (dwMemSize = 0) then Exit;  
pAll := VirtualAlloc(nil,dwMemSize+dwLen,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);  
if (pAll = nil) then Exit;  
dwSecCount := INH^.FileHeader.NumberOfSections;  
CopyMemory(pAll,IDH,DWord(SEC)-DWord(IDH)+dwSecCount*SizeOf(TImageSectionHeader));  
// CopyMemory(Pointer(DWord(pAll) + dwMemSize),pReserved,dwLen-1);  
CopyMemory(Pointer(DWord(pAll) + dwMemSize),nil,dwLen-1);  
for i := 0 to dwSecCount-1 do  
begin  
    CopyMemory(Pointer(DWord(pAll)+SEC^.VirtualAddress),  
          Pointer(DWord(pLib)+DWord(SEC^.PointerToRawData)),  
          SEC^.SizeOfRawData);  
    SEC := Pointer(Integer(SEC)+SizeOf(TImageSectionHeader));  
end;  
if (INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0) then  
    ChangeReloc(Pointer(INH^.OptionalHeader.ImageBase),  
          pAll,  
          Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),  
          INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);  
CreateImportTable(pAll, Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));  
@DllMain := Pointer(INH^.OptionalHeader.AddressOfEntryPoint+DWord(pAll));  
// if (INH^.OptionalHeader.AddressOfEntryPoint <> 0) and (bDllMain) then  
if INH^.OptionalHeader.AddressOfEntryPoint <> 0 then  
begin  
    try  
//      if (pReserved <> nil) then  
//        DllMain(DWord(pAll),DLL_PROCESS_ATTACH,DWord(pAll)+dwMemSize)  
//      else  
        DllMain(DWord(pAll),DLL_PROCESS_ATTACH,0);  
    except  
    end;  
end;  
Result := DWord(pAll);  
end;  
  
function memFreeLibrary(dwHandle: DWord): Boolean;  
var  
IDH: PImageDosHeader;  
INH: PImageNTHeaders;  
begin  
Result := false;  
if (dwHandle = 0) then  
    Exit;  
IDH := Pointer(dwHandle);  
if (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then  
    Exit;  
INH := Pointer(DWord(IDH^._lfanew)+DWord(IDH));  
if (INH^.Signature <> IMAGE_NT_SIGNATURE) then  
    Exit;  
if VirtualFree(Pointer(dwHandle),INH^.OptionalHeader.SizeOfImage,MEM_DECOMMIT) then  
    Result := True;  
end;  
  
function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;  
var  
NtHeader          : PImageNtHeaders;  
DosHeader          : PImageDosHeader;  
DataDirectory      : PImageDataDirectory;  
ExportDirectory    : PImageExportDirectory;  
i          : Integer;  
iExportOrdinal     : Integer;  
ExportName         : String;  
dwPosDot          : DWord;  
dwNewmodule        : DWord;  
pFirstExportName   : Pointer;  
pFirstExportAddress: Pointer;  
pFirstExportOrdinal: Pointer;  
pExportAddr        : PDWord;  
pExportNameNow     : PDWord;  
pExportOrdinalNow : PWord;  
begin  
Result := nil;  
if pFunctionName = nil then Exit;  
DosHeader := Pointer(dwLibHandle);  
if isBadReadPtr(DosHeader,sizeof(TImageDosHeader)) or (DosHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then  
    Exit; {Wrong PE (DOS) Header}  
NtHeader := Pointer(DWord(DosHeader^._lfanew)+DWord(DosHeader));  
if isBadReadPtr(NtHeader, sizeof(TImageNTHeaders)) or (NtHeader^.Signature <> IMAGE_NT_SIGNATURE) then  
    Exit; {Wrong PW (NT) Header}  
DataDirectory := @NtHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];  
if (DataDirectory = nil) or (DataDirectory^.VirtualAddress = 0) then  
    Exit; {Library has no exporttable}  
ExportDirectory := Pointer(DWord(DosHeader) + DWord(DataDirectory^.VirtualAddress));  
if isBadReadPtr(ExportDirectory,SizeOf(TImageExportDirectory)) then  
    Exit;  
pFirstExportName := Pointer(DWord(ExportDirectory^.AddressOfNames)+DWord(DosHeader));  
pFirstExportOrdinal := Pointer(DWord(ExportDirectory^.AddressOfNameOrdinals)+DWord(DosHeader));  
pFirstExportAddress := Pointer(DWord(ExportDirectory^.AddressOfFunctions)+DWord(DosHeader));  
if (integer(pFunctionName) > $FFFF) then {is FunctionName a PChar?}  
begin  
    iExportOrdinal := -1;          {if we dont find the correct ExportOrdinal}  
    for i := 0 to ExportDirectory^.NumberOfNames-1 do {for each export do}  
    begin  
      pExportNameNow := Pointer(Integer(pFirstExportName)+SizeOf(Pointer)*i);  
      if (not isBadReadPtr(pExportNameNow,SizeOf(DWord))) then  
      begin  
        ExportName := PChar(pExportNameNow^+ DWord(DosHeader));  
        if (ExportName = pFunctionName) then {is it the export we search? Calculate the ordinal.}  
        begin  
          pExportOrdinalNow := Pointer(Integer(pFirstExportOrdinal)+SizeOf(Word)*i);  
          if (not isBadReadPtr(pExportOrdinalNow,SizeOf(Word))) then  
          iExportOrdinal := pExportOrdinalNow^;  
        end;  
      end;  
    end;  
end else{no PChar, calculate the ordinal directly}  
    iExportOrdinal := DWord(pFunctionName)-DWord(ExportDirectory^.Base);  
if (iExportOrdinal < 0) or (iExportOrdinal > Integer(ExportDirectory^.NumberOfFunctions)) then  
    Exit; {havent found the ordinal}  
pExportAddr := Pointer(iExportOrdinal*4+Integer(pFirstExportAddress));  
if (isBadReadPtr(pExportAddr,SizeOf(DWord))) then  
    Exit;  
{Is the Export outside the ExportSection? If not its NT spezific forwared function}  
if (pExportAddr^ < DWord(DataDirectory^.VirtualAddress)) or  
     (pExportAddr^ > DWord(DataDirectory^.VirtualAddress+DataDirectory^.Size)) then  
begin  
    if (pExportAddr^ <> 0) then {calculate export address}  
      Result := Pointer(pExportAddr^+DWord(DosHeader));  
end  
else  
begin {forwarded function (like kernel32.EnterCriticalSection -> NTDLL.RtlEnterCriticalSection)}  
    ExportName := PChar(dwLibHandle+pExportAddr^);  
    dwPosDot := Pos('.',ExportName);  
    if (dwPosDot > 0) then  
    begin  
      dwNewModule := GetModuleHandle(PChar(Copy(ExportName,1,dwPosDot-1)));  
      if (dwNewModule = 0) then  
        dwNewModule := LoadLibrary(PChar(Copy(ExportName,1,dwPosDot-1)));  
      if (dwNewModule <> 0) then  
        result := GetProcAddressX(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName))));  
    end;  
end;  
end;  
end.  
转自:http://blog.youkuaiyun.com/aroc_lo/archive/2010/09/25/5904241.aspx

转载于:https://www.cnblogs.com/railgunman/archive/2010/11/27/1889721.html

Delphi内存加载DLL的高级封装技术 内存加载的基本原理是程序在运行时动态地将DLL代码加载到进程的地址空间中。与传统的文件系统加载方式不同,内存加载不依赖于硬盘上的DLL文件,而是直接将DLL的二进制代码映射到进程的内存空间。这使得程序可以减少对磁盘I/O操作的依赖,加快启动速度,并且能够更加灵活地控制DLL的生命周期。 阅读详情

相关推荐

Delphi程序实现动态加载DLL窗口的方法

创建动态链接库(DLL)是软件开发中常见的任务,尤其在需要模块化设计和提高代码复用率的场景下。DLL是一个或多个函数、数据和资源的集合,它们在一个单独的可执行文件中,可供一个或多个应用程序共享。在Delphi中创建和实现DLL涉及多个步骤,包括项目创建、窗口类的定义、函数导出以及资源的正确管理。在Windows编程中,窗口类是一个重要的概念。它定义了一个窗口的外观和行为,包括窗口所使用的窗口过程函数。一个窗口类需要在程序初始化时注册到系统中。以下是一个简化的窗口类的定义:public。

weixin_36474001的博客 1261

从内存中加载DLL Delphi版(转)

源:从内存中加载DLL DELPHI版 原文 : http://www.2ccc.com/article.asp?articleid=5784 MemLibrary.pas //从内存中加载DLL DELPHI版 unit MemLibrary; interface uses Windows; function memLoadLibrary(pLib: Po...

weixin_30832351的博客 336

深入掌握Delphi中的DLL应用与实战

本文还有配套的精品资源,点击获取 简介:本文深入探讨了Delphi编程语言中动态链接库(DLL)的应用及其相关知识点。DLL在Delphi中通过标准的Windows应用程序创建过程实现,其核心优势在于代码重用和模块化。DLL允许开发者构建插件系统和提供特定功能模块,例如Adobe Photoshop的插件机制。文章介绍了在Delphi中声明DLL函数的标准调用约定 ...

weixin_42350014的博客 1549

delphi 动态加载dll

返回参数类型string,必须在’uses’的最前面使用。,否则动态加载,FreeLibrary时会报错。.dpr文件的最前面,uses ShareMen。

qq_39011013的博客 738

DELPHI DLL注入技术详解与源码实践

DLL注入技术是计算机程序设计中的一项高级技术,它允许开发者将动态链接库(Dynamic Link Library,简称DLL)注入到另一个运行中的进程空间内。这种技术在软件开发、性能监控、安全研究等多个领域有着广泛的应用。本章节将为大家提供一个关于DLL注入技术的概览,包括它的工作原理、使用场景以及技术要点,为深入理解后续章节内容打下基础。DLL注入的原理是利用操作系统的API(应用程序编程接口)函数,将一个DLL文件映射到目标进程的地址空间内,并执行其导出函数,从而实现功能的动态扩展或修改。

weixin_35826166的博客 1112

delphi内存加载dll(支持xe2)

dll内存加载的delphi 源码,可以加载xe2 的dll

内存中加载DLL DELPHI版

//从内存中加载DLL DELPHI版 unit MemLibrary; interface uses Windows; function memLoadLibrary(pLib: Pointer): DWord; function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall; f

乐云天的博客 1876

用易语言解决“内存不能为read”

用易语言解决“内存不能为read”。 有的电脑总是出现“内存不能为read”的问题,用以语言可以解决了! (需要已经安装易语言。)

易语言LoadMemDll源码,易语言从内存加载DLL

易语言从内存加载DLL源码,从内存加载DLL,LoadMemLibrary,FreeMemLibrary,GetMemProcAddress,myMessageBox

Delphi 12.3控件之从内存加载DLL 1.rar

Delphi 12.3控件之从内存加载DLL [1].rar

Delphi 12.3控件之从内存加载DLL 3.rar

Delphi 12.3控件之从内存加载DLL [3].rar

Delphi从内存加载dll,无需从资源中释放dll

今天优快云的远程调用API终于恢复了访问,不过只能访问资源,不能发表!目前国内也很少有支持离线发布的博客了,唉。 下面是搜集来的关于如何不释放资源中的dll文件,直接从内存中加载dll ,Delphi版: 第一个例子:http://hi.baidu.com/broland/blog/item /6a42ed18812d1676dab4bd32.html 第二个例 子:http://2006ray.spaces.live.com/blog/cns!98ED6075D149E05D!114.en

醉客,ZuiKe,已醉过客 5622

保姆级教程:用Anaconda+PyCharm搞定YOLOv8本地部署(附避坑指南)

本文提供了一份详细的YOLOv8本地部署指南,涵盖Anaconda环境配置、PyCharm集成到模型部署的全过程。特别针对国内开发者需求,整合了镜像加速和常见报错解决方案,帮助快速完成目标检测模型的本地部署与实战应用。

weixin_42528090的博客 433
上一篇: 从内存中加载并运行exe(两种方法)
下一篇: 二进制文件转成文本保存,并可以读回
aowo7144
博客等级 码龄10年 5粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值