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

源:从内存中加载DLL DELPHI版

原文 : http://www.2ccc.com/article.asp?articleid=5784

MemLibrary.pas

//从内存中加载DLL DELPHI版  
unit MemLibrary;interfaceuses
Windows;function memLoadLibrary(pLib: Pointer): DWord;
function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;
function memFreeLibrary(dwHandle: DWord): Boolean;implementationprocedure ChangeReloc(baseorgp, basedllp, relocp: pointer; size: cardinal);
typeTRelocblock = recordvaddress: integer;size: integer;end;PRelocblock = ^TRelocblock;
varmyreloc: PRelocblock;reloccount: integer;startp: ^word;i: cardinal;p: ^cardinal;dif: cardinal;
beginmyreloc := relocp;dif := cardinal(basedllp)-cardinal(baseorgp);startp := pointer(cardinal(relocp)+8);while myreloc^.vaddress <> 0 dobeginreloccount := (myreloc^.size-8) div sizeof(word);for i := 0 to reloccount-1 dobeginif (startp^ xor $3000 < $1000) thenbeginp := 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;
typetimportblock = recordCharacteristics: cardinal;TimeDateStamp: cardinal;ForwarderChain: cardinal;Name: pchar;FirstThunk: pointer;end;pimportblock = ^timportblock;
varmyimport: pimportblock;thunksread, thunkswrite: ^pointer;dllname: pchar;dllh: thandle;old: cardinal;
beginmyimport := importp;while (myimport^.FirstThunk <> nil) and (myimport^.Name <> nil) dobegindllname := pointer(integer(dllbasep)+integer(myimport^.name));dllh := LoadLibrary(dllname);thunksread := pointer(integer(myimport^.FirstThunk)+integer(dllbasep));thunkswrite := thunksread;if integer(myimport^.TimeDateStamp) = -1 thenthunksread := pointer(integer(myimport^.Characteristics)+integer(dllbasep));while (thunksread^ <> nil) dobeginif VirtualProtect(thunkswrite,4,PAGE_EXECUTE_READWRITE,old) thenbeginif (cardinal(thunksread^) and $80000000 <> 0) thenthunkswrite^ := GetProcAddress(dllh,pchar(cardinal(thunksread^) and $FFFF)) elsethunkswrite^ := 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) thenExit;INH := pointer(cardinal(pLib)+cardinal(IDH^._lfanew));
if isBadReadPtr(INH, SizeOf(TImageNtHeaders)) or (INH^.Signature <> IMAGE_NT_SIGNATURE) thenExit;// if (pReserved <> nil) then
//    dwLen := Length(pReserved)+1
// elsedwLen := 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
beginCopyMemory(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) thenChangeReloc(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
begintry
//      if (pReserved <> nil) then
//        DllMain(DWord(pAll),DLL_PROCESS_ATTACH,DWord(pAll)+dwMemSize)
//      elseDllMain(DWord(pAll),DLL_PROCESS_ATTACH,0);exceptend;
end;
Result := DWord(pAll);
end;function memFreeLibrary(dwHandle: DWord): Boolean;
var
IDH: PImageDosHeader;
INH: PImageNTHeaders;
begin
Result := false;
if (dwHandle = 0) thenExit;IDH := Pointer(dwHandle);
if (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) thenExit;INH := Pointer(DWord(IDH^._lfanew)+DWord(IDH));
if (INH^.Signature <> IMAGE_NT_SIGNATURE) thenExit;if VirtualFree(Pointer(dwHandle),INH^.OptionalHeader.SizeOfImage,MEM_DECOMMIT) thenResult := 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) thenExit; {Wrong PE (DOS) Header}NtHeader := Pointer(DWord(DosHeader^._lfanew)+DWord(DosHeader));
if isBadReadPtr(NtHeader, sizeof(TImageNTHeaders)) or (NtHeader^.Signature <> IMAGE_NT_SIGNATURE) thenExit; {Wrong PW (NT) Header}DataDirectory := @NtHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (DataDirectory = nil) or (DataDirectory^.VirtualAddress = 0) thenExit; {Library has no exporttable}ExportDirectory := Pointer(DWord(DosHeader) + DWord(DataDirectory^.VirtualAddress));
if isBadReadPtr(ExportDirectory,SizeOf(TImageExportDirectory)) thenExit;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?}
beginiExportOrdinal := -1;          {if we dont find the correct ExportOrdinal}for i := 0 to ExportDirectory^.NumberOfNames-1 do {for each export do}beginpExportNameNow := Pointer(Integer(pFirstExportName)+SizeOf(Pointer)*i);if (not isBadReadPtr(pExportNameNow,SizeOf(DWord))) thenbeginExportName := PChar(pExportNameNow^+ DWord(DosHeader));if (ExportName = pFunctionName) then {is it the export we search? Calculate the ordinal.}beginpExportOrdinalNow := Pointer(Integer(pFirstExportOrdinal)+SizeOf(Word)*i);if (not isBadReadPtr(pExportOrdinalNow,SizeOf(Word))) theniExportOrdinal := 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)) thenExit; {havent found the ordinal}pExportAddr := Pointer(iExportOrdinal*4+Integer(pFirstExportAddress));
if (isBadReadPtr(pExportAddr,SizeOf(DWord))) thenExit;{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
beginif (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) thenbegindwNewModule := GetModuleHandle(PChar(Copy(ExportName,1,dwPosDot-1)));if (dwNewModule = 0) thendwNewModule := LoadLibrary(PChar(Copy(ExportName,1,dwPosDot-1)));if (dwNewModule <> 0) thenresult := GetProcAddressX(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName))));end;
end;
end;end.

 

转载于:https://www.cnblogs.com/LittleTiger/p/4437063.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420003.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 定时执行kettle6,linux下使用crond定时执行kettle的job

由于第一次碰linux&#xff0c;对其不是很了解&#xff0c;导致这个问题困扰了我近一个月的时间&#xff0c;现在终于解决了&#xff0c;分享给大家。首先&#xff0c;安装jre&#xff0c;配置java环境变量(一)下载jre-6u23-linux-x64.bin下载地址&#xff1a;http://cds-esd.s…

【leetcode】ZigZag Conversion

题目简述 The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line: "PA…

ld-linux.so.2 重定向,2-Linux重定向和管道、Shell编程.doc

2-Linux重定向和管道、Shell编程评 分实验报告课程名称&#xff1a; 操作系统实验名称&#xff1a; Red Hat Linux操作系统的运用专 业&#xff1a; 信息与计算科学成 员&#xff1a; 庄小俪指导教师&#xff1a; 陆星家完成日期&#xff1a; 2013 年 9月 24日实验二 Linux的重…

linux中文乱码

txt文件在linux环境下打开呈现了乱码状态。 解决方法1&#xff1a;在linux用iconv命令&#xff0c;如乱码文件名为zhongwen.txt&#xff0c;那么在终端输入如下命令&#xff1a; iconv -f gbk -t utf8 zhongwen.txt > zhongwen.txt.utf8 如果eclipse打开后仍是乱码&#xff…

c语言用for编程图形,C语言编程题求解

2009-05-13C语言简单的编程题求解1.从键盘输入一//将四个函数编成四个子函数了&#xff0c;在一个主函数里调用&#xff0c;你若需要&#xff0c;分别取出来用也可以。以下源代码&#xff0c;VS2005编译通过。//1。从键盘输入一行字符&#xff0c;分别统计其中字母字符和数字字…

2.3线性表的链式存储和运算—单链表应用举例

例2.5 已知单链表H&#xff0c;写一算法将其倒置。即实现如图2.22的操作。(a)为倒置前&#xff0c;(b)为倒置后。 算法思路&#xff1a;依次取原链表中的每个结点&#xff0c;将其作为第一个结点插入到新链表中去&#xff0c;指针p用来指向当前结点&#xff0c;p为空时结束。 算…

c语言see函数,vprintf() - C语言库函数

C库函数 int vprintf(const char *format, va_list arg) 发送格式化输出到stdout使用一个参数列表传递给它。声明以下是 vprintf() 函数的声明。intvprintf(constchar*format,va_list arg)参数format -- 这是包含文本的字符串被写入到缓冲。它可以包含嵌入的格式在随后的附加…

js获取checkbox值的方法

js获取checkbox值的方法。分享给大家供大家参考。具体实现方法如下&#xff1a;<html> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"> <title>js</title> </head> <script language&q…

c语言占用cpu的程序,Windows下用C语言获取进程cpu使用率,内存使用,IO情况

转自&#xff1a; http://zhangyafeikimi.iteye.com/blog/378658process_stat.h/** file * brief 进程统计信息函数的声明 * author 张亚霏 * date 2009/05/03 * version 0.1 * */ #ifndef PROCESS_STAT_H #define PROCESS_STAT_H #ifdef __cplusplus extern "C" { #…

oracle 本地使用命令导入数据到远程主机

第一步:装载oracle客户端 第二部:配置tnsnames.ora.  db_172.21.1.7 (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST 172.21.1.7)(PORT 1526))(CONNECT_DATA (SERVER DEDICATED)(SERVICE_NAME db))) 第三部:打开命令行,执行如下命令: imp netelnusr/netelnusrdb_172.21.1.7…

c语言计算据标准时间多少天,C语言系列--时间处理

首先明确几个概念UTC 协调世界时&#xff0c;又称世界标准时间或世界协调时间。GMT 格林尼治平均时间或格林尼治标准時間&#xff0c;由于地球每天的自转是有些不规则的&#xff0c;而且正在缓慢减速&#xff0c;因此格林威治时间已经不再被作为标准时间使用日历时间&#xff0…

Perl学习笔记(六)--文件(一)

一、文件描述符&#xff1a; 访问文件时用来代表文件的数字。 它是系统资源&#xff0c;系统限制打开的文件描述符数量。 Perl中只在某些系统调用时才使用它 文件句柄&#xff1a; 功能同文件描述符&#xff0c;但是与文件描述符不是一个东西。 Perl使用文件句柄代表文件。 文件…

android mkdirs 不起作用,Android mkdirs()创建一个零字节文件而不是文件夹

在我的Android应用程序中,我试图在SD卡上创建以下文件夹&#xff1a;/mnt/sdcard/OSGiComponents/admin/felix-cache/这是代码&#xff1a;File cacheDir new File( Environment.getExternalStorageDirectory().getAbsolutePath() "/OSGiComponents/admin/felix-cache/&qu…

向ComboBox列表框中添加Enum的全部数据

相当于利用反射的 GetValues与GetNames foreach (HETieXinType theType in Enum.GetValues(typeof(HETieXinType))) foreach (string mode in Enum.GetNames(typeof(BooleanInteractionMode))) { ledResponseModesComboBox.Items.Add(mode); switchResponseModesComboBox.Items…

android sqlite 备份数据库文件,android – 将SQLite数据库备份和还原到sdcard

这是我的代码&#xff1a;// Local databaseInputStream input new FileInputStream(from);// create directory for backupFile dir new File(DB_BACKUP_PATH);dir.mkdir();// Path to the external backupOutputStream output new FileOutputStream(to);// transfer bytes…

Spring中配置数据源的4种形式 ---转

不管采用何种持久化技术&#xff0c;都需要定义数据源。Spring中提供了4种不同形式的数据源配置方式&#xff1a; spring自带的数据源(DriverManagerDataSource)&#xff0c;DBCP数据源&#xff0c;C3P0数据源,JNDI数据源。 1.spring自带的数据源 DriverManagerDataSource XML…

android中拖动文字实现功能,Android:图片中叠加文字,支持拖动改变位置

之所以做了这么一个Demo&#xff0c;是因为最近项目中有一个奇葩的需求&#xff1a;用户拍摄照片后&#xff0c;分享到微信的同时添加备注&#xff0c;想获取用户在微信的弹出框输入的内容&#xff0c;保存在自己的服务器上。而事实上&#xff0c;这个内容程序是无法获取的&…

Mac 下nginx 环境的配置

这个是在度娘那里学来的。 因为是使用brew所以先安装&#xff1a; 安装命令如下&#xff1a;curl -LsSf http://github.com/mxcl/homebrew/tarball/master | sudo tar xvz -C/usr/local --strip 1当brew安装成功后&#xff0c;就可以随意安装自己想要的软件了&#xff0c;例如w…

android抽屉屏幕右滑,android - Android - 使滑动抽屉从左向右滑动 - 堆栈内存溢出...

我使用下面的XML布局在我的应用程序中实现了“Sliding Drawer”:(我从androidpeople.com得到了这个例子)android:layout_width"fill_parent" android:layout_height"fill_parent"xmlns:android"http://schemas.android.com/apk/res/android"andr…

bzoj 3196/tyvj p1730 二逼平衡树

原题链接&#xff1a;http://www.tyvj.cn/p/1730 树套树。。。 如下&#xff1a; 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #define lc root<<1 6 #define rc root<<1|1 7 #define INF…