您好,欢迎来到[编程问答]网站首页   源码下载   电子书籍   软件下载   专题
当前位置:首页 >> 编程问答 >> Delphi >> 难题100分求助,在线等待,调用DLL文件流中中的函数

难题100分求助,在线等待,调用DLL文件流中中的函数

来源:网络整理     时间:2016/8/25 2:58:45     关键词:

关于网友提出的“ 难题100分求助,在线等待,调用DLL文件流中中的函数”问题疑问,本网通过在网上对“ 难题100分求助,在线等待,调用DLL文件流中中的函数”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: 难题100分求助,在线等待,调用DLL文件流中中的函数
描述:

现在把一个dll作为RES加入到当前的项目中生成一个.exe文件,原.exe本来要调用dll的函数的,但是现在dll作为资源了,不想把这个资源释放到计算机硬盘上,想直接在文件流中使用,不知道有什么好的方法?
由于是第一次做DELPHI项目,还请达人能够稍微说得详细一点,谢谢!!!!


解决方案1:

// 继续
procedure ProcessRelocs(PRelocs:PImageBaseRelocation);
var
  PReloc: PImageBaseRelocation;
  RelocsSize: cardinal;
  Reloc: PWord;
  ModCount: cardinal;
  RelocLoop: cardinal;
begin
  PReloc := PRelocs;
  RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
  while cardinal(PReloc) - cardinal(PRelocs) < RelocsSize do
  begin
    ModCount := (PReloc.SizeOfBlock-Sizeof(PReloc^)) div 2;
    Reloc := pointer(cardinal(PReloc)+sizeof(PReloc^));
    for RelocLoop := 0 to ModCount - 1 do
    begin
      if Reloc^ and $f000 <> 0 then
        Inc(pdword(cardinal(ImageBase) + PReloc.VirtualAddress + (Reloc^ and $0fff))^, ImageBaseDelta);
      Inc(Reloc);
    end;
    PReloc := pointer(Reloc);
  end;
end;
procedure ProcessImports(PImports: PImageImportDescriptor);
var
  PImport: PImageImportDescriptor;
  Import: LPDword;
  PImportedName: pchar;
  LibHandle: HModule;
  ProcAddress: pointer;
  PLibName: pchar;
  ImportLoop: integer;
function IsImportByOrdinal(ImportDescriptor: dword; HLib: THandle): boolean;
begin
  Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;
end;
begin
  PImport := PImports;
  while PImport.Name<>0 do
  begin
    PLibName := pchar(cardinal(PImport.Name) + cardinal(ImageBase));
    if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
    begin
      LibHandle := LoadLibrary(PLibName);
      Add(NewLibInfo.LibsUsed, PLibName);
    end
    else
      LibHandle := cardinal(NewLibInfo.LibsUsed[ImportLoop]);
    if PImport.TimeDateStamp = 0 then
      Import := LPDword(pImport.FirstThunk+cardinal(ImageBase))
    else
      Import := LPDword(pImport.OriginalFirstThunk + cardinal(ImageBase));
    while Import^ <> 0 do
    begin
      if IsImportByOrdinal(Import^, LibHandle) then
        ProcAddress := GetProcAddress(LibHandle, pchar(Import^ and $ffff))
      else
      begin
        PImportedName := pchar(Import^ + cardinal(ImageBase) + IMPORTED_NAME_OFFSET);
        ProcAddress := GetProcAddress(LibHandle, PImportedName);
      end;
      PPointer(Import)^ := ProcAddress;
      Inc(Import);
    end;
    Inc(PImport);
  end;
end;
begin
  ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);
  ImageBase := VirtualAlloc(nil, ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_NOACCESS);
  ImageBaseDelta := cardinal(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;
  SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);
  Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);
  VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, PAGE_READONLY, OldProtect);
  PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
  for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
  begin
    VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;
    RawSectionSize := PSections[SectionLoop].SizeOfRawData;
    if VirtualSectionSize < RawSectionSize then
    begin
      VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
      RawSectionSize := VirtualSectionSize xor RawSectionSize;
      VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
    end;
    SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);
    FillChar(SectionBase^, VirtualSectionSize, 0);
    Move((pchar(src) + PSections[SectionLoop].PointerToRawData)^, SectionBase^, RawSectionSize);
  end;
  NewLibInfo.DllProc := TDllEntryProc(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));
  NewLibInfo.ImageBase := ImageBase;
  SetLength(NewLibInfo.LibsUsed, 0);
  if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0 then
    ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + cardinal(ImageBase)));
  if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0 then
    ProcessImports(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + cardinal(ImageBase)));
  for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
    VirtualProtect(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), PSections[SectionLoop].Misc.VirtualSize, GetSectionProtection(PSections[SectionLoop].Characteristics), OldProtect);
  if @NewLibInfo.DllProc <> nil then
  begin
    if not NewLibInfo.DllProc(cardinal(ImageBase), DLL_PROCESS_ATTACH, nil) then
    begin
      NewLibInfo.DllProc := nil;
      xFreeLibrary(Result);
    end;
  end;
  if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress <> 0 then
    ProcessExports(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + cardinal(ImageBase)), ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
  Result := NewLibInfo;
end;
end.


以上介绍了“ 难题100分求助,在线等待,调用DLL文件流中中的函数”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3582631.html

相关图片

相关文章