博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从内存中加载DLL DELPHI版
阅读量:5129 次
发布时间:2019-06-13

本文共 9139 字,大约阅读时间需要 30 分钟。

 

//从内存中加载DLL DELPHI版  unit MemLibrary;interfaceusesWindows;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);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;varDllMain    : function (dwHandle, dwReason, dwReserved: DWord): DWord; stdcall;IDH        : PImageDosHeader;INH        : PImageNtHeaders;SEC        : PImageSectionHeader;dwSecCount : DWord;dwLen      : DWord;dwmemsize : DWord;i          : Integer;pAll       : Pointer;beginResult := 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 dobegin    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) thenif INH^.OptionalHeader.AddressOfEntryPoint <> 0 thenbegin    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;varIDH: PImageDosHeader;INH: PImageNTHeaders;beginResult := 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;varNtHeader          : 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;beginResult := 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)) thenbegin if (pExportAddr^ <> 0) then {
calculate export address} Result := Pointer(pExportAddr^+DWord(DosHeader));endelsebegin {
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.

转载于:https://www.cnblogs.com/MaxWoods/p/3706194.html

你可能感兴趣的文章
C# - 泛型委托
查看>>
咏南开发框架调用存储过程演示
查看>>
Jackson2.1.4 序列化对象时,过滤null的属性 empty的属性 default的属性
查看>>
DevStack添加Swift
查看>>
RadControls for Silverlight Q2 2012 试用版探究
查看>>
Handling bundles in activities and fragments
查看>>
数据仓库的设计目的
查看>>
Linux C高级编程——网络编程基础(1)
查看>>
IOS版本号被拒的经历
查看>>
JavaScript 本地对象、内置对象、宿主对象
查看>>
servlet的url-pattern匹配规则详细描述
查看>>
spring boot 整合 云之讯 demo
查看>>
《大型网站技术架构》1:概述
查看>>
(PatchGANs)Pecomputed Real-time Texture Synthesis With Markovian Generative Adversarial Networks
查看>>
Anjular的ng-repeat
查看>>
Gas Station,转化为求最大序列的解法,和更简单简单的Jump解法。——贪心、转化...
查看>>
MTK android 工程中如何修改照片详细信息中机型名
查看>>
Use delegation to write map/filter in Java
查看>>
html5用canvas对图片压缩
查看>>
opacity设定图片透明度
查看>>