//从内存中加载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)+);
while myreloc^.vaddress <> do
begin
reloccount := (myreloc^.size-) div sizeof(word);
for i := to reloccount- do
begin
if (startp^ xor $ < $) then
begin
p := pointer(myreloc^.vaddress+startp^ mod $+integer(basedllp));
p^ := p^+dif;
end;
startp := pointer(cardinal(startp)+sizeof(word));
end;
myreloc := pointer(startp);
startp := pointer(cardinal(startp)+);
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) = - then
thunksread := pointer(integer(myimport^.Characteristics)+integer(dllbasep));
while (thunksread^ <> nil) do
begin
if VirtualProtect(thunkswrite,,PAGE_EXECUTE_READWRITE,old) then
begin
if (cardinal(thunksread^) and $ <> ) then
thunkswrite^ := GetProcAddress(dllh,pchar(cardinal(thunksread^) and $FFFF)) else
thunkswrite^ := GetProcAddress(dllh,pchar(integer(dllbasep)+integer(thunksread^)+));
VirtualProtect(thunkswrite,,old,old);
end;
inc(thunksread,);
inc(thunkswrite,);
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 := ;
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)+
// else
dwLen := ;
SEC := Pointer(Integer(INH)+SizeOf(TImageNtHeaders));
dwMemSize := INH^.OptionalHeader.SizeOfImage;
if (dwMemSize = ) 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-);
CopyMemory(Pointer(DWord(pAll) + dwMemSize),nil,dwLen-);
for i := to dwSecCount- 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 <> ) 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 <> ) and (bDllMain) then
if INH^.OptionalHeader.AddressOfEntryPoint <> then
begin
try
// if (pReserved <> nil) then
// DllMain(DWord(pAll),DLL_PROCESS_ATTACH,DWord(pAll)+dwMemSize)
// else
DllMain(DWord(pAll),DLL_PROCESS_ATTACH,);
except
end;
end;
Result := DWord(pAll);
end; function memFreeLibrary(dwHandle: DWord): Boolean;
var
IDH: PImageDosHeader;
INH: PImageNTHeaders;
begin
Result := false;
if (dwHandle = ) 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 = ) 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 := -; {if we dont find the correct ExportOrdinal}
for i := to ExportDirectory^.NumberOfNames- 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 < ) or (iExportOrdinal > Integer(ExportDirectory^.NumberOfFunctions)) then
Exit; {havent found the ordinal}
pExportAddr := Pointer(iExportOrdinal*+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^ <> ) 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 > ) then
begin
dwNewModule := GetModuleHandle(PChar(Copy(ExportName,,dwPosDot-)));
if (dwNewModule = ) then
dwNewModule := LoadLibrary(PChar(Copy(ExportName,,dwPosDot-)));
if (dwNewModule <> ) then
result := GetProcAddressX(dwNewModule,PChar(Copy(ExportName,dwPosDot+,Length(ExportName))));
end;
end;
end;
end.

从内存中加载DLL DELPHI版的更多相关文章

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

    源:从内存中加载DLL DELPHI版 原文 : http://www.2ccc.com/article.asp?articleid=5784 MemLibrary.pas //从内存中加载DLL D ...

  2. 内存中加载DLL DELPHI版

    //从内存中加载DLL DELPHI版 unit MemLibrary; interface uses Windows; function memLoadLibrary(pLib: Pointer): ...

  3. 在内存中加载DLL

    有个需求是把一个DLL作为数据打包到EXE中,运行的时候动态加载.但要求不是释放出来生成DLL文件加载. 花了一天时间做出来.效果还可以. 不过由于是直接分配内存加载DLL的.有一些小缺陷.例如遍历进 ...

  4. 从内存中加载并启动一个exe

    windows似乎只提供了一种启动进程的方法:即必须从一个可执行文件中加载并启动.而下面这段代码就是提供一种可以直接从内存中启动一个exe的变通办法.用途嘛, 也许可以用来保护你的exe,你可以对要保 ...

  5. 如何在uboot上实现从网络下载版本镜像并直接在内存中加载之?

    这是作者近期项目上遇到的一个需求,描述如下: 一块MT7620N的路由器单板,Flash中已存放一个版本并可以通过uboot正常加载并启动.现在需要:在uboot上电启动过程中,通过外部按键触发干涉, ...

  6. 内存加载DLL

    1.前言 目前很多敏感和重要的DLL(Dynamic-link library) 都没有提供静态版本供编译器进行静态连接(.lib文件),即使提供了静态版本也因为兼容性问题导致无法使用,而只提供DLL ...

  7. C# 实现动态加载DLL插件 及HRESULT:0x80131047处理

    本代码实现DLL的动态加载, 类似PS里的滤镜插件! 1. 建立一个接口项目类库,此处名称为:Test.IPlugin using System; namespace Test.IPlugin { p ...

  8. java 加载dll介绍(转)

    最近在做的工作要用到本地方法,需要在Java中加载不少动态链接库(以下为方便延用Windows平台下的简写dll,但并不局限于Windows).刚刚把程序跑通,赶紧把一些心得写出来,mark.也希望对 ...

  9. c#实现动态加载Dll(转)

    c#实现动态加载Dll 分类: .net2009-12-28 13:54 3652人阅读 评论(1) 收藏 举报 dllc#assemblynullexceptionclass 原理如下: 1.利用反 ...

随机推荐

  1. Linux下利用backtrace追踪函数调用堆栈以及定位段错误【转】

    转自:https://www.linuxidc.com/Linux/2012-11/73470p2.htm 通常情况系,程序发生段错误时系统会发送SIGSEGV信号给程序,缺省处理是退出函数.我们可以 ...

  2. nc用法【转】

    linux nc命令使用详解 功能说明:功能强大的网络工具 语 法:nc [-hlnruz][-g<网关...>][-G<指向器数目>][-i<延迟秒数>][-o& ...

  3. css初始化minireset.css

    一个很小的现代CSS重置,涵盖了基本内容: 重置字体大小:这样使用语义标记不会影响样式 重置块边距:所以只有在需要时才应用间距 重置表格:这样表格数据只占用它所需的空间 保留了行内间距:因此,按钮和输 ...

  4. 点击超链接打开本地QQ

    2014年6月4日 10:20:18 张志斌 这个功能实际上是属于腾讯的推广项目"一键加群"功能: http://qun.qq.com/join.html 用户必须有自己的群,登录 ...

  5. eclipse导入项目报错multiple annotations found at this line

    eclipsewindow-->preference-->Valdation-->将Manual和Build下复选框全部取消选择

  6. 防雪崩利器:熔断器 Hystrix 的原理与使用

    1.概述 分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况, 这种现象被称为服务雪崩效应. 为了应对服务雪崩, 一种常见的做法是手动服务降级. 而Hystrix的出现,给我们提供了另一 ...

  7. 如何在Axure中使用FontAwesome字体图标

    Font Awesome为您提供可缩放的矢量图标,您可以使用CSS所提供的所有特性对它们进行更改,包括:大小.颜色.阴影或者其它任何支持的效果. FontAwesome应用在web网页开发中非常方便, ...

  8. 从 prototype.js 深入学习 javascript 的面向对象特性

    从 prototype.js 深入学习 javascript 的面向对象特性 js是一门很强大的语言,灵活,方便. 目前我接触到的语言当中,从语法角度上讲,只有 Ruby 比它更爽. 不过我接触的动态 ...

  9. 【noip模拟赛3】编码

    描述 Alice和Bob之间要进行秘密通信,他们正在讨论如何对信息进行加密: Alice:“不如采用一种很简单的加密方式:’A’替换成1,’B’替换成2,„„,’Z’替换成26.” Bob:“这种加密 ...

  10. 前馈神经网络练习:使用tensorflow进行葡萄酒种类识别

    数据处理 样本数据描述 样本数据集是double类型的178 * 14矩阵,第一列表示酒所属类别,后面13列分别表示当前样本的13个属性: 1) Alcohol 2) Malic acid 3) As ...